wolfchart/index.htm

3821 lines
318 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 10]>
<html lang='en' class='old_ie'>
<![endif]-->
<html lang=en>
<head>
<meta charset="utf-8" />
<title>WolfChart</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAdCAMAAAD8QJ61AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBQTFRFqamphoaGxcXF1tbW9/f3U1NTLi4uurq64+PjnZ2ddHR07Ozsk5OTAAAA////////NZC25gAAABB0Uk5T////////////////////AOAjXRkAAAFRSURBVHjadFNZYsUgCATU4AJ6/9sWFVP72vJhCA4wLMK4hUoYHwKXHgp3xj4I+C9AQw6994ZIHZjpF6DGviTPL2YuF4ARGofoCJfSDyDX3CPUzuXc1XlAPAB0c3pcacozC0rcAHeMj4IH0LotAjcAVB8PoOqxpBtAyDOYPewAqu5U4oCSPYOZNU1tKk4nWYRDXXRdPM/66nZrGF5A0h9ySsOTIv68PzkMELEtOh+AzXcCRsS8M6QyD+OQxI6rFeK1W5+qNrSPvDkwOsBrsMhozutntpvZGhXhroHq0VZP0AB5QjOk3QA+0Af3zGE09lYuZ5q4BOS7gfe4eycj+uzYPovJYQSp4SyCyilwjS37yr0xzP2d5AxwdjLQPRDrbFi8iN6txskpeztsd4SsvRG/1z4ai1BFxEAFZT4vKNLudwE2lRHJctH/T8+klPJh+RJgAA5sKxGB5VuMAAAAAElFTkSuQmCC" />
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1">
<style type="text/css">
.old_ie .setting-bar,
.old_ie .guide-section,
.old_ie .setting-button {
display: none;
}
.IENotice {
display: none;
}
.old_ie .IENotice {
display: block!important;
width: 100%;
height: 100%;
}
.old_ie .IENotice .modal{
display: block!important;
text-align: center;
background: white;
padding: 20px ;
color: #000;
margin: 10% auto 0;
font-size: 20px;
}
* {
margin: 0;
box-sizing: border-box;
padding: 0;
}
a {
color: #337ab7;
text-decoration: none;
}
a:active, a:hover {
color: #337ab7;
text-decoration: underline;
}
html {
height: -webkit-fill-available;
}
body {
font-family: Helvetica, Arial, San serif;
font-size: 16px;
color: #666666;
line-height: 1.2;
overflow: hidden;
/*mobile viewport fix*/
min-height: -webkit-fill-available;
min-height: 100vh;
}
.setting-bar {
right: 0;
-webkit-transition: all 0.3s linear;
transition: all 0.3s linear;
position: fixed;
top: 0;
border: 1px solid rgba(0,0,0,0.20);
height: 100%;
background: #F4F4F4;
box-shadow: -2px 0 4px rgba(0,0,0,0.30);
padding: 30px 20px;
overflow-y: auto;
-webkit-transform: translateX(560px);
transform: translateX(560px);
z-index: 19;
}
.mask {
opacity: 0;
visibility: hidden;
position: fixed;
width: 100%;
height: 100%;
z-index: 8;
background: rgba(0,0,0,0.6);
left: 0;
top: 0;
-webkit-transition: all 0.3s linear;
transition: all 0.3s linear;
pointer-events: none;
}
.active.mask {
opacity: 1;
visibility: visible;
}
.setting-bar.active {
-webkit-transform: translateX(0);
transform: translateX(0);
}
.guide-section {
right: 0;
-webkit-transition: all 0.3s linear;
transition: all 0.3s linear;
position: fixed;
top: 0;
height: 100%;
z-index: 10;
background: #fff;
box-shadow: -2px 0 4px rgba(0,0,0,0.30);
padding: 30px;
overflow-y: auto;
width: calc(100vw - 560px - 50px);
-webkit-transform: translateX(100vw);
transform: translateX(100vw);
}
.guide-section.active {
-webkit-transform: translateX(-538px);
transform: translateX(-538px);
}
.form-control {
height: 38px;
font-size: 16px;
border-radius: 5px;
border: 1px solid #DBDBDB;
display: inline-block;
vertical-align: middle;
width: 100%;
padding: 5px 10px;
font-family: Helvetica, Arial, San serif;
font-size: 16px;
color: #666666;
background: white;
}
.form-control:focus, .form-control:active {
outline: none;
}
.form-group label {
display: table-cell;
padding-left: 20px;
}
.filter-hue {
background: hsl(0,0%,85%);
padding: 25px 0 10px 0;
margin-bottom: 20px;
border-radius: 10px;
}
.col-1 {
display: table-cell;
min-width: 343px;
}
.col-2 {
display: table-cell;
min-width: 190px;
}
.col-4 {
display: table-cell;
min-width: 120px;
}
.col-8 {
display: table-cell;
width: 308px;
}
.col-12 {
display: table-cell;
width: 103px;
}
.form-control + .unit {
margin-left: 5px;
}
.red {
color: #D30000;
font-size: 12px;
}
.form-group {
display: table;
margin: 0 0 20px 0;
}
.input-sm {
width: 90px;
}
.input-med {
width: 210px;
}
.fg-divider {
margin:10px 5px 20px 5px;
}
.select-box {
position: relative;
}
.keyboard {
margin-right: 5px;
}
.select-box:after {
content: "";
border: 1px solid #666;
border-top: none;
border-right: none;
display: block;
height: 10px;
position: absolute;
right: 15px;
top: 10px;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
width: 10px;
pointer-events: none;
}
legend, h2 {
font-size: 32px;
padding: 0 0 20px 0;
}
fieldset {
border: none;
border-top: 1px solid #979797;
padding-top: 40px;
position: relative;
}
fieldset .title {
position: absolute;
right: 0;
color: white;
text-transform: uppercase;
top: 0;
text-align: center;
}
fieldset .title span {
background: #666;
display: block;
float: left;
width: 134px;
font-size: 13px;
height: 22px;
line-height: 24px;
}
fieldset .title a {
background: #999999;
height: 22px;
margin-right: 2px;
width: 22px;
display: block;
float: left;
color: #fff;
line-height: 24px;
text-decoration: none;
}
select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
fieldset.footer-fieldset {
padding-top: 30px;
}
.close, .close-guide {
position: absolute;
right: 30px;
top: 35px;
}
.btn {
padding: 10px 12px;
background: #F4F4F4;
border-radius: 5px;
border: 1px solid #979797;
font-size: 15px;
text-align: center;
color: #666666;
cursor: pointer;
min-width: 150px;
}
.btn:hover {
opacity: 0.8;
}
.btn + .btn {
margin-left: 5px;
}
.action-button {
text-align: right;
margin-bottom: 30px;
}
.col-setting {
position: relative;
}
.col-setting i {
width: 30px;
height: 30px;
border-radius: 4px;
border:solid 1px gray;
position: absolute;
top: 10%;
left: 165px;
}
.slider {
-webkit-appearance: none;
position: absolute;
left: 40%;
width: 55%;
height: 10px;
border-radius: 5px;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.red-slide {
background: hsl(0,80%,60%);
}
.green-slide {
background: hsl(160,80%,60%);
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
border: solid 2px rgba(50,50,50,1);
background: rgba(100,100,100,0.5);
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 15px;
height: 15px;
border-radius: 50%;
border: solid 2px rgba(50,50,50,1);
background: rgba(100,100,100,0.5);
cursor: pointer;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
.action-button {
margin: 0;
}
}
.btn-primary {
border-color: #2d689d;
}
.btn-tiny {
padding: 6px 6px;
border-radius: 4px;
border: 1px solid #979797;
font-size: 15px;
color: #666666;
cursor: pointer;
min-width: 50px;
}
.btn[disabled] {
cursor: not-allowed;
opacity: 0.3;
}
/*accordion*/
.panel-title a {
display: block;
padding: 10px;
background: #666666;
color: white;
text-decoration: none;
font-size: 16px;
position: relative;
font-weight: normal;
}
.panel-title a:after {
width: 0;
content: "";
height: 0;
border-style: solid;
border-width: 9px 7px 0 7px;
border-color: #ffffff transparent transparent transparent;
position: absolute;
display: block;
right: 10px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.collapse {
display: none;
}
.panel {
margin-bottom: 2px;
}
.panel-heading.active .panel-title a:after {
-webkit-transform: translateY(-50%) rotate(180deg);
transform: translateY(-50%) rotate(180deg);
}
.panel-collapse {
padding: 10px;
}
.scoreBox {
font: bold 5.5mm helvetica,arial, sans-serif;
position: absolute;
width: 57px;
top: 50%;
transform: translateY(-50%);
margin-top: 0 !important;
background: #d8d8d8;
border-radius: 5px;
color: #000;
padding: 3px 3px;
transition: all 0.1s linear;
border: 1px solid transparent;
left: 3px;
cursor: pointer;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
.scoreBox:hover {
box-shadow: 0 0 3px rgba(0,0,0,0.3);
border-color: red;
z-index: 9;
}
.scoreBox.active {
box-shadow: 0 0 3px rgba(0,0,0,0.3);
background-color: red;
color: rgba(0,0,0,1);
z-index: 9;
}
.rule label {
position: relative;
}
.rule label:before, .rule label:after {
background: black none repeat scroll 0 0;
content: "";
display: block;
height: 10px;
left: 20px;
position: absolute;
top: 7px;
width: 1px;
}
.rule label:after {
left: auto;
right: 0;
}
#letterChart {
position: relative;
text-align: center;
margin: 0;
z-index: 0;
}
#letterChart .character-line {
position: relative;
line-height: 0;
font-size: 0;
width: 100%;
}
.duo {
background-size: 100%;
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,0,0,1) 50%, rgba(0,200,127,1) 50%, rgba(0,200,127,1) 100%);
}
#letterChart .char-line {
display: inline-block;
z-index: 1;
}
#otherChart {
position: relative;
text-align: center;
margin: 0;
z-index: 0;
}
.chart {
height: 100%;
width: 100%;
display: none;
}
.clear-both {
height: 0;
clear: both;
}
.panel ul {
margin-left: 15px;
}
.panel ul li {
margin: 10px 0;
}
body {
margin: 0 auto;
}
.char-line {
margin-left: 0 !important;
margin-right: 0 !important;
}
.char-line svg {
margin-top: 0 !important;
margin-bottom: 0 !important;
float: left;
cursor: pointer;
}
.char-line svg.disable {
opacity: 0;
visibility: hidden;
}
.char-line svg.active {
opacity: 1;
visibility: visible;
}
/*get dpi*/
#dpi {
height: 1in;
left: -100%;
position: absolute;
top: -100%;
width: 1in;
}
.disabled-btn {
background: #ccc;
border: #ccc;
filter: opacity(0.3);
pointer-events: none;
}
.disabled-fg {
pointer-events: none;
filter:opacity(.2);
}
.errorMsg {
color: red;
font-size: 12px;
display: block;
margin-top: 10px;
}
.character-invisible {
visibility: hidden;
opacity: 0;
}
.modal-setting {
position: fixed;
z-index: 9;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0,0,0,0.3);
}
#side-bar {
background: linear-gradient(0deg, rgba(138, 138, 138, 1) 0%, rgba(204, 204, 204, 1) 50%);
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2), 0 0 3px 3px rgba(0, 0, 0, 0.19);
position:absolute;
width: 80px;
right:0px;
text-align: center;
height:100%;
z-index: 14;
}
.setting-button a {
display: block;
position: relative;
width: 42px;
height: 42px;
margin: 0 auto;
z-index: 9;
}
.setting-button svg {
position: relative;
top: 20px;
}
#clock-div {
display: block;
position: relative;
top: 30px;
width: 100%;
color: rgb(255,255,255);
font: 800 20px sans-serif;
}
#button-div {
display: block;
position: relative;
top: 40px;
}
#arrow-button-div {
display: block;
position: relative;
width:100%;
}
#arrow-button-div a {
cursor: pointer;
display:block;
text-decoration: none;
margin:0.5em 0;
}
.arrow-button {
width:52px;
}
#pic-arrow-div {
display: block;
position: relative;
margin: 0 auto;
top: 20px;
}
#pic-arrow-div a {
cursor: pointer;
display:block;
text-decoration: none;
margin: 0.5em 0;
}
.pic-arrow {
margin:-0.5em 0;
}
#function-button-div {
display: block;
position: relative;
margin: 0 auto;
top: 40px;
}
#function-button-div a {
cursor: pointer;
display:block;
text-decoration: none;
margin:0.5em 0;
}
#function-button-div svg {
width: 52px;
}
#thisBadge {
display: block;
text-align: center;
margin: 20px 0;
}
#nav-button-outer-div {
display:block;
position:fixed;
overflow:hidden;
right:0px;
bottom:40px;
background-color: transparent;
}
#nav-button-div {
display: block;
border-radius:31px 0 0 31px;
background-color: rgb(204,204,204);
position:relative;
height:62px;
transform:translate(80%,0);
transition:0.2s ease-in-out;
}
#nav-button-div a{
cursor: pointer;
text-decoration: none;
display:inline-block;
height:100%;
width:62px;
padding:10px;
}
#nav-button-div.expanded {
transform:translate(0,0);
}
/* Animista slide animations */
.slide-out-top{-webkit-animation:slide-out-top .2s cubic-bezier(.215,.61,.355,1.000) both;animation:slide-out-top .2s cubic-bezier(.215,.61,.355,1.000) both}
.slide-out-right{-webkit-animation:slide-out-right .2s cubic-bezier(.215,.61,.355,1.000) both;animation:slide-out-right .2s cubic-bezier(.215,.61,.355,1.000) both}
.slide-out-bottom{-webkit-animation:slide-out-bottom .2s cubic-bezier(.215,.61,.355,1.000) both;animation:slide-out-bottom .2s cubic-bezier(.215,.61,.355,1.000) both}
.slide-out-left{-webkit-animation:slide-out-left .2s cubic-bezier(.215,.61,.355,1.000) both;animation:slide-out-left .2s cubic-bezier(.215,.61,.355,1.000) both}
.slide-in-top{-webkit-animation:slide-in-top .2s cubic-bezier(.25,.46,.45,.94) both;animation:slide-in-top .2s cubic-bezier(.25,.46,.45,.94) both}
.slide-in-right{-webkit-animation:slide-in-right .2s cubic-bezier(.25,.46,.45,.94) both;animation:slide-in-right .2s cubic-bezier(.25,.46,.45,.94) both}
.slide-in-bottom{-webkit-animation:slide-in-bottom .2s cubic-bezier(.25,.46,.45,.94) both;animation:slide-in-bottom .2s cubic-bezier(.25,.46,.45,.94) both}
.slide-in-left {-webkit-animation: slide-in-left 0.2s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;animation: slide-in-left 0.2s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;}
@-webkit-keyframes slide-out-top{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}100%{-webkit-transform:translateY(-1000px);transform:translateY(-1000px);opacity:0}}@keyframes slide-out-top{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}100%{-webkit-transform:translateY(-1000px);transform:translateY(-1000px);opacity:0}}
@-webkit-keyframes slide-out-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(1000px);transform:translateX(1000px);opacity:0}}@keyframes slide-out-right{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(1000px);transform:translateX(1000px);opacity:0}}
@-webkit-keyframes slide-out-bottom{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}100%{-webkit-transform:translateY(1000px);transform:translateY(1000px);opacity:0}}@keyframes slide-out-bottom{0%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}100%{-webkit-transform:translateY(1000px);transform:translateY(1000px);opacity:0}}
@-webkit-keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}}@keyframes slide-out-left{0%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}}
@-webkit-keyframes slide-in-right{0%{-webkit-transform:translateX(1000px);transform:translateX(1000px);opacity:0}100%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes slide-in-right{0%{-webkit-transform:translateX(1000px);transform:translateX(1000px);opacity:0}100%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}
@-webkit-keyframes slide-in-left{0%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}100%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}@keyframes slide-in-left{0%{-webkit-transform:translateX(-1000px);transform:translateX(-1000px);opacity:0}100%{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}}
@-webkit-keyframes slide-in-bottom{0%{-webkit-transform:translateY(1000px);transform:translateY(1000px);opacity:0}100%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes slide-in-bottom{0%{-webkit-transform:translateY(1000px);transform:translateY(1000px);opacity:0}100%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}
@-webkit-keyframes slide-in-top{0%{-webkit-transform:translateY(-1000px);transform:translateY(-1000px);opacity:0}100%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes slide-in-top{0%{-webkit-transform:translateY(-1000px);transform:translateY(-1000px);opacity:0}100%{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}
@media only screen and (max-width: 1024px) {
/* For tablets */
#side-bar {
width: 50px;
}
#clock-div {
display: none;
}
#side-bar>a svg {
width: 28px;
}
#arrow-button-div {
top: 20px;
}
#arrow-button-div>a svg {
width: 28px;
}
#thisBadge>svg {
width: 40px;
}
#pic-arrow-div {
margin: 0 auto;
top: 40px;
}
#pic-arrow-div>a svg {
width: 28px;
}
#pic-arrow-div a {
margin: 0.5em 0;
}
.pic-arrow {
margin:-0.5em 0;
}
#function-button-div {
top: 60px;
}
#function-button-div svg {
width: 28px;
}
}
</style>
</head>
<body>
<!--dpi-->
<div id="dpi"></div>
<!--setting bar-->
<div id="side-bar">
<a class="setting-button" href="#setting-bar">
<svg id="bHamburger" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 14 12" width="42px">
<defs></defs>
<rect x="1" y="1" width="12" height="10" rx="1" fill="none" stroke-width="0.75" stroke="rgb(102,102,102)"></rect>
<rect x="2.5" y="3" width="9" height="1" rx="0.5" fill="rgb(102,102,102)" stroke-width="0"></rect>
<rect x="2.5" y="5.5" width="9" height="1" rx="0.5" fill="rgb(102,102,102)" stroke-width="0"></rect>
<rect x="2.5" y="8" width="9" height="1" rx="0.5" fill="rgb(102,102,102)" stroke-width="0"></rect>
</svg>
</a>
<div id="clock-div"></div>
<div id="button-div">
<div id="arrow-button-div">
<a id="btRight"></a>
<a id="btLeft"></a>
<a id="thisBadge"></a>
</div>
<div id="pic-arrow-div">
<a id="btUp"></a>
<a id="btDn"></a>
</div>
<div id="function-button-div">
<a id="btSpacebarFunc"></a>
<a id="btShuffleFunc"></a>
<a id="btBgFunc"></a>
</div>
</div>
<div id="nav-button-outer-div">
<div id="nav-button-div">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4"
style="height:62px;margin-right:-5px;">
<path d="M4 0V4H2A2 2 0 0 1 2 0z" fill="rgb(114,114,114)" stroke-width="0" />
<circle cx="1.5" cy="2" r="0.25" fill="rgb(255,255,255)" />
<circle cx="2.3" cy="2" r="0.25" fill="rgb(255,255,255)" />
<circle cx="3.1" cy="2" r="0.25" fill="rgb(255,255,255)" />
</svg>
</div>
</div>
</div>
<div class="setting-bar" id="setting-bar">
<a class="close" href="#">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="1 1 16 16" enable-background="new 1 1 16 16" xml:space="preserve" style="width:24px;height:24px">
<g id="Layer_7" display="none">
<rect x="1" y="1" display="inline" width="16" height="16" />
</g>
<g id="Layer_31">
<path fill="#68707D" d="M12.1,11.6c0.1,0.1,0.1,0.3,0,0.5c-0.1,0.1-0.2,0.1-0.2,0.1c-0.1,0-0.2,0-0.2-0.1L9,9.5l-2.6,2.6
c-0.1,0.1-0.2,0.1-0.2,0.1c-0.1,0-0.2,0-0.2-0.1c-0.1-0.1-0.1-0.3,0-0.5L8.5,9L5.9,6.4C5.8,6.2,5.8,6,5.9,5.9
c0.1-0.1,0.3-0.1,0.5,0L9,8.5l2.6-2.6c0.1-0.1,0.3-0.1,0.5,0c0.1,0.1,0.1,0.3,0,0.5L9.5,9L12.1,11.6z M9,16.5L9,16.5L9,16.5z
M9,1.2C4.7,1.2,1.2,4.7,1.2,9c0,2.1,0.8,4,2.3,5.5C4.9,16,6.9,16.8,9,16.8h0c4.3,0,7.8-3.5,7.8-7.8C16.8,4.7,13.3,1.2,9,1.2L9,1.2
z" />
</g>
</svg>
</a>
<form action="" method="" id="form-setting">
<legend>Settings</legend>
<fieldset>
<div class="title">
<a class="questions-btn" href="#character-set">?</a> <span>OPTOTYPES</span>
</div>
<div class="form-group" id="fgOptotype">
<label class="col-2" for="sOptotype" >Optotype</label>
<div class="col-8 select-box">
<select class="form-control" id="sOptotype">
<option value="1">Snellen</option>
<option value="2">Sloan</option>
<option value="3">LandoltC</option>
<option value="4">TumblingE</option>
<option value="5">Vanishing Sloan</option>
<option value="6">Shapes</option>
<option value="7">Chinese (beta)</option>
<option value="8">Arabic (beta)</option>
<option value="9">Hebrew</option>
<!-- <option value="10">Crowded HOTV</option> -->
</select>
</div>
</div>
<div class="form-group" id="fgAlphabet">
<label class="col-2" for="sAlphabet" >Alphabet</label>
<div class="col-8 select-box">
<select class="form-control" id="sAlphabet">
<option value="2">BS4274.3</option>
<option value="1">SnellenU</option>
</select>
</div>
</div>
</fieldset>
<fieldset>
<div class="title">
<a class="questions-btn" href="#distance">?</a> <span>RECORDING</span>
</div>
<div class="form-group" id="fgNotation">
<label class="col-2" for="sNotation" >Notation</label>
<div class="col-8 select-box">
<select class="form-control" id="sNotation">
<option value="1">Metres</option>
<option value="2">Feet</option>
<option value="3">logMAR</option>
<option value="4">DecimalV</option>
</select>
</div>
</div>
<div class="form-group" id="fgNumerator">
<label class="col-2" for="sNumerator" >Numerator</label>
<div class="col-8 select-box">
<select class="form-control" id="sNumerator">
<option value="2">Standard</option>
<option value="1">Actual</option>
</select>
</div>
</div>
</fieldset>
<fieldset>
<div class="title">
<a class="questions-btn" href="#calibration">?</a> <span>CALIBRATION</span>
</div>
<div class="form-group" id="fgDistance">
<label class="col-2" for="iDistance" >Distance <span style="color:red">*</span></label>
<div class="col-8 ">
<input type="text" class="form-control input-sm" id="iDistance" title="Chart Distance" min="3000"> <span class="unit">mm</span>
</div>
</div>
<div class="form-group" id="fgLengthOfLine">
<label class="col-2" for="iLengOfLine" >Length of line below<span style="color:red">*</span></label>
<div class="col-8 ">
<input type="text" class="form-control input-sm" id="iLengOfLine" title="Length of Calibration Line" min="25" max="250"> <span class="unit">mm</span> <span class="red">(be precise)</span>
</div>
</div>
<div class="rule form-group">
<label>
<svg width="120mm" viewBox="0 0 120 1" xmlns="http://www.w3.org/2000/svg">
<rect fill="rgba(20,220,30,1)" stroke="none" x="0" y="0" width="120" height="1" id="calib_line" />
</svg>
</label>
</div>
</fieldset>
<fieldset>
<div class="title">
<a class="questions-btn" href="#options">?</a> <span>options</span>
</div>
<div class="form-group" id="fgSort">
<label class="col-2" for="display" >Sort</label>
<div class="col-8 select-box">
<select class="form-control" id="display">
<option value="1" selected>Smallest to Largest</option>
<option value="2">Largest to Smallest</option>
<option value="3">Monoyer</option>
</select>
</div>
</div>
<div class="form-group" id="fgMirrored">
<label class="col-2" for="sMirrored" >Mirrored / Direct</label>
<div class="col-8 select-box">
<select class="form-control" id="sMirrored">
<option value="2" selected="selected">Mirrored</option>
<option value="1">Direct</option>
</select>
</div>
</div>
<hr class="fg-divider" />
<div class="form-group" id="fgOptoColour">
<label class="col-2" for="tOptoColour" >Optotype colour</label>
<div class="col-setting">
<input type="text" id="tOptoColour" class="form-control input" value="rgba(0,0,0,1)" /><i> </i>
</div>
</div>
<div class="form-group" id="fgPresetsOpto">
<label class="col-2" for="bt100Blk" >Presets: <button class="btn btn-tiny col-preset-opto" id="bt100Blk" type="button" value="rgba(0,0,0,1)">100% Black</button>
</label>
<div class="">
<button class="btn btn-tiny col-preset-opto" id="bt10Blk" type="button" value="rgba(0,0,0,0.1)">10% Black</button>
<button class="btn btn-tiny col-preset-opto" id="bt100Red" type="button" value="rgba(255,0,0,1)">100% Red</button>
<button class="btn btn-tiny col-preset-opto" id="bt100Blue" type="button" value="rgba(0,0,255,1)">100% Blue</button>
</div>
</div>
<hr class="fg-divider" />
<div class="form-group" id="fgBgColour">
<label class="col-2" for="tBgColour" >Background colour</label>
<div class="col-setting">
<input type="text" id="tBgColour" class="form-control input" value="rgba(255,255,255,1)" /><i></i>
</div>
</div>
<div class="form-group" id="fgPresetsBg">
<label class="col-2" for="bt100Wh" >Presets: <button class="btn btn-tiny col-preset-bg" id="bt100Wh" type="button" value="rgba(255,255,255,1)">100% White</button>
</label>
<div class="">
<button class="btn btn-tiny col-preset-bg" id="bt90Blk" type="button" value="rgba(0,0,0,0.9)">90% Black</button>
<button class="btn btn-tiny col-preset-bg" id="bt50Blk" type="button" value="rgba(0,0,0,0.5)">50% Black (mid-grey)</button>
</div>
</div>
</fieldset>
<fieldset>
<div class="title">
<a class="questions-btn" href="#filters">?</a> <span>r/l filters</span>
</div>
<div class="filter-hue">
<div class="form-group" id="fgFilterRed">
<label class="col-2" for="sliderRed" >Filter Red Hue</label>
<div class="">
<input type="range" min="340" max="380" value="360" class="slider red-slide" id="sliderRed">
</div>
</div>
<div class="form-group" id="fgFilterGreen">
<label class="col-2" for="sliderGreen" >Filter Green/Blue Hue</label>
<div class="">
<input type="range" min="110" max="200" value="160" class="slider green-slide" id="sliderGreen">
</div>
</div>
</div>
</fieldset>
<fieldset>
<div class="title">
<a class="questions-btn" href="#shortcuts">?</a> <span>shortcuts</span>
</div>
<div class="form-group" id="fgPageUL">
<label class="col-4" for="pageUp" >Page Up</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="pageUp" maxlength="1" value="u">
</div>
<label class="col-4" for="pageLeft" >Page Left</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="pageLeft" maxlength="1" value="g">
</div>
</div>
<div class="form-group" id="fgPageDR">
<label class="col-4" for="pageDown" >Page Down</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="pageDown" maxlength="1" value="n">
</div>
<label class="col-4" for="pageRight" >Page Right</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="pageRight" maxlength="1" value="k">
</div>
</div>
<div class="form-group" id="fgShuffle">
<label class="col-1" for="shuffle" >Toggle Shuffle</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="shuffle" maxlength="1" value="q">
</div>
</div>
<div class="form-group" id="fgDuochrome">
<label class="col-1" for="duoBG" >Toggle Duochrome</label>
<div class="col-12">
<input type="text" class="form-control input-sm js-shortkey" id="duoBG" maxlength="1" value="z">
</div>
</div>
</fieldset>
<fieldset class="footer-fieldset">
<div class="action-button">
<button class="btn btn-default" id="reset" type="button">Reset to defaults</button>
<button class="btn btn-default btn-primary disabled-btn" id="updateSetting" type="button">Apply</button>
</div>
</fieldset>
</form>
</div>
<!--end setting bar-->
<!-- guide section-->
<div id="guide-section" class="guide-section">
<legend>Help</legend>
<a class="close-guide" href="#">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="1 1 16 16" enable-background="new 1 1 16 16" xml:space="preserve" style="width:24px;height:24px">
<g id="Layer_7" display="none">
<rect x="1" y="1" display="inline" width="16" height="16" />
</g>
<g id="Layer_31">
<path fill="#68707D" d="M12.1,11.6c0.1,0.1,0.1,0.3,0,0.5c-0.1,0.1-0.2,0.1-0.2,0.1c-0.1,0-0.2,0-0.2-0.1L9,9.5l-2.6,2.6
c-0.1,0.1-0.2,0.1-0.2,0.1c-0.1,0-0.2,0-0.2-0.1c-0.1-0.1-0.1-0.3,0-0.5L8.5,9L5.9,6.4C5.8,6.2,5.8,6,5.9,5.9
c0.1-0.1,0.3-0.1,0.5,0L9,8.5l2.6-2.6c0.1-0.1,0.3-0.1,0.5,0c0.1,0.1,0.1,0.3,0,0.5L9.5,9L12.1,11.6z M9,16.5L9,16.5L9,16.5z
M9,1.2C4.7,1.2,1.2,4.7,1.2,9c0,2.1,0.8,4,2.3,5.5C4.9,16,6.9,16.8,9,16.8h0c4.3,0,7.8-3.5,7.8-7.8C16.8,4.7,13.3,1.2,9,1.2L9,1.2
z" />
</g>
</svg>
</a>
<div class="panel-body">
<strong>Very quick guide: </strong>Calibrate and configure your chart using the Settings form and consult this help guide if you get stuck. You will need a measuring tape to measure viewing distance and a ruler to measure the calibration line.<br />Charts are in 4 categories; V for VA, R for Refraction, B for Binocular and M for Miscellaneous. Use the onscreen arrows or arrows on your keyboard to navigate horizontally between categories and vertically within categories. Alternatively, the category buttons in the flyout at bottom right give you one-click access to your most-used chart in that category. These category links are also mapped to the corresponding letters on your keyboard.<br />Click or tap on any line label to mask that line. Click or tap again to unmask. <br />Click or tap on any letter to mask it. Click or tap on it again to mask a column of letters. Click or tap on any letter in the column to show all again. <br />If there is a round button in the sidebar below the navigation arrows, the chart has a function mapped to the spacebar, such as zoom or rotate. You can also activate the function by clicking on or tapping the chart itself or the button.<br /><strong>Why is one of the charts just black?</strong><br />So you can darken your room with one click.<br /><br />
</div>
<div class="accordion">
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="character-set">
<h4 class="panel-title">
<a href="#">
Optotypes
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
The optotypes fields allow you to select the symbols to be displayed. You cannot change the array nor order of the lines displayed here.
<ul>
<li>
<strong>Optotype</strong>: Select from a range of standard optotypes.
</li>
<li>
<strong>Alphabet</strong>: The available options are dependent on the OPTOTYPE selected above. SnellenU and SloanU use a wider selection of letters, but letters may not be of equal readability. BS4724.3 and ETDRS are standard alphabets using fewer letters, but with more equal readability. Letters can be shuffled to prevent learning and increase repeatability - see below
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="distance">
<h4 class="panel-title">
<a href="#">
Recording
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
<ul>
<li>
<strong>Notation</strong>: Sets the notation type on the VA label on each chart line. Regardless of notation or optotype, WolfChart uses the standard logMAR array of subtenses (0.501", 0.631", 0.794", 1", 1.259", 1.585", 2", 2.512", 3.162", 3.981", 5.012", 6.31", 7.943", 10") with each 3 lines doubling the subtense. Notation and Numerator express these subtenses as your preferred VA value. "Metres" is standard Snellen notation eg. 6/6; "Feet" is the imperialist equivalent eg. 20/20; DecimalV is a the European standard (EN ISO 8596) eg. 6/60 = 0.1, 6/12 = 0.5; logMAR is explained here <a href="https://en.wikipedia.org/wiki/LogMAR_chart" target="_blank">https://en.wikipedia.org/wiki/LogMAR_chart.</a>
</li>
<li>
<strong>Numerator</strong>: Sets the numerator of the fraction notation types only; if Notation is set to logMar or DecimalV, this setting makes no difference.<br />"Standard" is either 6 or 20 depending whether Notation is set to Metres or Feet above. VA labels will display as either 6/ or 20/ regardless of the value in Distance.<br />"Actual" is the value entered in Distance (see below) rounded to the nearest 0.1m or 0.5ft, and VA labels will show this rounded numerator, with a ! instead of a /, and a proportionally adjusted denominator. Please note that it is not advisable to use Standard if the Distance varies a large amount from 6000mm, say outside 5500-6500mm. The numerator should be the tested distance or near to it.
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="calibration">
<h4 class="panel-title">
<a href="#">
Calibration
</a>
</h4>
</div>
<div id="collapseThree" class="panel-collapse collapse">
<div class="panel-body">
<p> The two CALIBRATION values are the <strong>only</strong> values that influence the size of the letters. The RECORDING values above only change the VA labels on the letter chart lines, and have no bearing on the letters themselves.</p>
<ul>
<li><strong>Distance</strong>: Enter the distance from the patient's eye to the letter chart in mm. Eg 6m is 6000mm. Even if you work in feet (see Notation above), you <strong>must</strong> enter the Distance in mm. If using a mirror to double the test distance, measure BOTH from the patient's eye to the mirror AND from the mirror to the display and ADD the two distances (and don't forget to check the Mirrored/Direct setting - see below). If you are using Notation value of "Feet", Numerator will be converted to the nearest foot, or to 20 depending on the value in Numerator.</li>
<li>
<strong>Length of the line below</strong>: Calibrates the chart. WolfChart does not need to know anything about the screen you are using; it just needs the length of this green line as it is displayed. Measure the length of the green line as accurately as possible. On a touch screen this is tricky, but you'll work it out. You will need to re-check this value if you change display hardware, graphics adapter settings, or if you turn your display from landscape to portrait or vice versa. Take particular care here if you are using extended display from a computer as pixel density may be different between the computer screen and the external display.
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="options">
<h4 class="panel-title">
<a href="#">
Options
</a>
</h4>
</div>
<div id="collapseFour" class="panel-collapse collapse">
<div class="panel-body">
<ul>
<li><strong>Sort</strong>: Unless the display is very large (about 1m wide by about 1.5m tall viewed at 6m), the letter chart will display in pages - see SHORTCUTS below. Here you can select whether to display the page of the smallest or largest lines first. If French, you have a Monoyer option. </li>
<li><strong>Mirrored/Direct</strong>: Select "Direct" if WolfChart is to be viewed directly, otherwise select "Mirrored" and the letters and lines will be reversed, but the labels not. If changing this setting, don't forget to set the Distance (see above) accordingly.</li>
<li><strong>Optotype colour</strong>: Defaults to solid black. Enter any valid rgba string or use the preset buttons for common values.</li>
<li><strong>Background colour</strong>: Defaults to solid white. Enter any valid rgba string or use the preset button/s. If a Vanishing optotype is selected, this field is disabled.</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="filters">
<h4 class="panel-title">
<a href="#">
R/L Filter Hues
</a>
</h4>
</div>
<div id="collapseFive" class="panel-collapse collapse">
<div class="panel-body">
WolfChart uses red and green targets for binocular dissociation tests. The default hues may work fine for your filters, but if not, you can set the hues using the sliders. The objective is for each slider to be only visible from one eye using red/green or red/blue goggles or trial set filters. Sometimes you can't get total invisibility, or there are two invisible settings. In either case the tests will work if you can make the two hues as different as possible when viewed through each coloured filter.
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="shortcuts">
<h4 class="panel-title">
<a href="#">
Shortcuts
</a>
</h4>
</div>
<div id="collapseSix" class="panel-collapse collapse">
<div class="panel-body">
<p> Use these fields to specify keyboard shortcuts for operating WolfChart. Certain keys eg. v, r, b and m are reserved and you will be alerted not to use them if you try.</p>
<ul>
<li>
<strong>Page Up/Dn/Left/Right</strong>: Page Up, Down, Left and Right are already mapped to the arrows on your keyboard, and the arrow buttons on screen. If your controller doesn't have arrow keys, add custom shortcuts here, eg u,n,g and k respectively<br />
</li>
<li>
<strong>Shuffle:</strong>: Toggles shuffle of the letters. Each shuffle is random, but each unshuffle returns the alphabet to it's original order.
</li>
<li>
<strong>Duochrome:</strong>: Toggles a red/green background on V charts.
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!--end guide-section-->
<div id="letterChart" style="height:100%;">
<div data-line="1" class="character-line">
<div class="char-line" id="line-1"></div>
</div>
<div data-line="2" class="character-line">
<div class="char-line" id="line-2"></div>
</div>
<div data-line="3" class="character-line">
<div class="char-line" id="line-3"></div>
</div>
<div data-line="4" class="character-line">
<div class="char-line" id="line-4"></div>
</div>
<div data-line="5" class="character-line">
<div class="char-line" id="line-5"></div>
</div>
<div data-line="6" class="character-line">
<div class="char-line" id="line-6"></div>
</div>
<div data-line="7" class="character-line">
<div class="char-line" id="line-7"></div>
</div>
<div data-line="8" class="character-line">
<div class="char-line" id="line-8"></div>
</div>
<div data-line="9" class="character-line">
<div class="char-line" id="line-9"></div>
</div>
<div data-line="10" class="character-line">
<div class="char-line" id="line-10"></div>
</div>
<div data-line="11" class="character-line">
<div class="char-line" id="line-11"></div>
</div>
<div data-line="12" class="character-line">
<div class="char-line" id="line-12"></div>
</div>
<div data-line="13" class="character-line">
<div class="char-line" id="line-13"></div>
</div>
<div data-line="14" class="character-line">
<div class="char-line" id="line-14"></div>
</div>
</div>
<div id="otherChart">
<!--these hidden divs below represent a chart each, using class for categorising.
They are hidden in the head style.
Letter charts (class='chart V') are created dynamically in PageLetterChart() -->
<div class="chart R" id="R0" style="background-color: rgba(255,255,255,1);">
<svg id="rJCCDots" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"
width="200px">
<defs></defs>
<g id="layer0" style="display:none;">
<circle cx="2" cy="10" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="6" cy="4" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="6" cy="16" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="10" cy="10" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="14" cy="4" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="14" cy="16" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="18" cy="10" r="2" fill="rgba(0,0,0,1)" stroke="none"></circle>
</g>
<g id="layer1">
<circle cx="2" cy="6" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="2" cy="10" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="2" cy="14" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="6" cy="4" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="6" cy="8" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="6" cy="12" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="6" cy="16" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="10" cy="2" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="10" cy="6" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="10" cy="10" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="10" cy="14" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="10" cy="18" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="14" cy="4" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="14" cy="8" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="14" cy="12" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="14" cy="16" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="18" cy="6" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle><circle cx="18" cy="10" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
<circle cx="18" cy="14" r="1" fill="rgba(0,0,0,1)" stroke="none"></circle>
</g>
</svg>
</div>
<div class="chart R" id="R1" style="background-color: rgba(255,255,255,1);">
<svg id="rBullseye" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 14 14" width="200px">
<defs></defs>
<g id="layer0" style="display:none;">
<path
d="M 7 0 A 7 7 0 1 1 6.999 0z M 7 2 A 5 5 0 1 1 6.999 2z M 7 4 A 3 3 0 1 1 6.999 4z M 7 6 A 1 1 0 1 1 6.999 6z"
fill="#000000" stroke="none" fill-rule="evenodd"></path>
</g>
<g id="layer1">
<path
d="M 7 3.5 A 3.5 3.5 0 1 1 6.999 3.5z M 7 4.5 A 2.5 2.5 0 1 1 6.999 4.5z M 7 5.5 A 1.5 1.5 0 1 1 6.999 5.5z M 7 6.5 A 0.5 0.5 0 1 1 6.999 6.5z"
fill="#000000" stroke="none" fill-rule="evenodd"></path>
</g>
</svg>
</div>
<div class="chart R" id="R2" style="background-color: rgba(255,255,255,1);">
<svg id="rSeptumChart" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 40 28" width="200px">
<defs></defs>
<g id="layer0">
</g>
<g id="layer1" transform="">
<g id="scChart" transform="translate (10,1.5)">
<g id="scRGroup" transform="translate (15,0)">
<g id="scTURN" transform="translate(2,0)">
<path d="M0 0H4V1H2.5V5H1.5V1H0z" fill="#000000" transform="translate(0,2)" stroke-width="0">
</path>
<path d="M0 0V3A2 2 0 0 0 4 3V0H3V3A1 1 0 1 1 1 3 V0z" fill="#000000"
transform="translate(0.79,10) scale(0.63)" stroke-width="0"></path>
<path
d="M 0 0 H 2.5 A 1.5 1.5 0 0 1 2.5 3 L 4 5 H 2.8 L 1.3 3 H 1 V 5 H 0 V 1 H 1 V 2 H 2.5 A 0.5 0.5 0 0 0 2.5 1 H 0 V 0"
fill="#000000" transform="translate(1.1,16) scale (0.47)" stroke-width="0"></path>
<path d="M0 0H1L3 3.1V0H4V5H3L1 1.9V5H0z" fill="#000000" transform="translate(1.33,21) scale(0.33)"
stroke-width="0"></path>
</g>
<path d="M8 0 H0V0.5H7.5V24.5H0V25H8z" fill="#000000" transform=""
stroke-width="0"></path>
</g>
<g id="scLGroup" transform="translate (-3,0)">
<g id="scHELP" transform="translate(2,0)">
<path d="M0 0H1V2H3V0H4V5H3V3H1V5H0z" fill="#000000" transform="translate(0,2)" stroke-width="0">
</path>
<path d="M0 0H4V1H1V2H3V3H1V4H4V5H0z" fill="#000000" transform="translate(0.63,10) scale(0.67)"
stroke-width="0"></path>
<path d="M 0 0H1V4H4V5H0z" fill="#000000" transform="translate(1,16) scale (0.47)" stroke-width="0">
</path>
<path d="M 0 0H2.5A 1.5 1.5 0 0 1 2.5 3H1V5H0V1H1V2H2.5A 0.5 0.5 0 0 0 2.5 1H0z" fill="#000000"
transform="translate(1.33,21) scale(0.33)" stroke-width="0"></path>
</g>
<path d="M0 0H8V0.5H0.5V24.5H8V25H0z" fill="#000000" transform=""
stroke-width="0"></path>
</g>
</g>
</g>
</svg>
</div>
<div class="chart B" id="B0" style="background-color:hsl(0,0%,90%);">
<svg id="bFixDisp" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 28 26" width="200px" style="border: 1px black;">
<defs></defs>
<g>
<rect x="1" y="10.5" width="26" height="5" stroke-width="0.1" fill="#ffffff" stroke="#000000"></rect>
<circle cx="9" cy="13" r="1.5" fill="none" stroke="#000000" stroke-width="1"></circle>
<path d="M13.5 11H14.5V12.5H16V13.5H14.5V15H13.5V13.5H12V12.5H13.5V11" fill="#000000" stroke-width="0">
</path>
<circle cx="19" cy="13" r="1.5" fill="none" stroke="#000000" stroke-width="1"></circle>
<path class="filterGreen" d="M13 1H15V10H13V1" fill="#2cd72c" stroke-width="0"></path>
<path class="filterRed" d="M13 16H15V25H13V15" fill="#d42c2c" stroke-width="0"></path>
</g>
</svg>
</div>
<div class="chart B" id="B1" style="background-color:hsl(0,0%,90%);">
<svg id="bWorth4Dot" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 35 35" width="200px">
<defs></defs>
<g id="layer0" style="display:none">
<circle class="filterGreen" cx="17.5" cy="15" r="1" fill="#2cd72c" stroke-width="0"></circle>
<circle class="filterRed" cx="15" cy="17.5" r="1" fill="#d42c2c" stroke-width="0"></circle>
<circle class="filterRed" cx="20" cy="17.5" r="1" fill="#d42c2c" stroke-width="0"></circle>
<circle cx="17.5" cy="20" r="1" fill="rgba(0,0,0,1)" stroke-width="0"></circle>
</g>
<g id="layer1">
<circle class="filterGreen" cx="17.5" cy="10" r="2.5" fill="#2cd72c" stroke-width="0"></circle>
<circle class="filterRed" cx="10" cy="17.5" r="2.5" fill="#d42c2c" stroke-width="0"></circle>
<circle class="filterRed" cx="25" cy="17.5" r="2.5" fill="#d42c2c" stroke-width="0"></circle>
<circle cx="17.5" cy="25" r="2.5" fill="rgba(0,0,0,1)" stroke-width="0"></circle>
</g>
</svg>
</div>
<div class="chart M" id="M0" style="background-color: rgba(0,0,0,1);">
</div>
<div class="chart M" id="M1" style="background-color: rgba(0,0,0,1);">
<svg id="mWhiteDot" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 10 10" width="200px" style="background-color: rgba(0,0,0,1);">
<defs></defs>
<g id="layer0" style="display:none;">
<circle cx="5" cy="5" r="5" fill="rgba(255,255,255,1)" stroke="none"></circle>
</g>
<g id="layer1">
<circle cx="5" cy="5" r="2.5" fill="rgba(255,255,255,1)" stroke="none"></circle>
</g>
</svg>
</div>
<div class="chart M animated" id="M2" style="background-color: rgba(0,0,0,1);">
<svg id="mLetterMorph" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" width="200px">
<defs>
<mask id="letterMask">
<rect x="1" y="1" width="2" height="3" fill="#fff" />
</mask>
</defs>
<polygon id="SVGLetter" points="" fill="hsl(0,50%,50%)" fill-rule="evenodd">
<animate id="morph0" attributeName="points" dur="0.35s" fill="freeze"
from="0,0 1,0 1,2 3,2 3,0 4,0 4,5 3,5 3,3 1,3 1,5 0,5"
to="0,0 0,0 1,0 1,0 1,4 1,4 4,4 4,4 4,5 4,5 0,5 0,5"
/>
</polygon>
</svg>
</div>
<div class="chart M animated" id="M3" style="background-color: rgba(0,0,0,1);">
<svg id="mMilesElam" version="1.1" width="200px" viewBox="0 0 320 320" fill="none" stroke="#fff"
stroke-linecap="round" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="r1">
<animate id="p1" attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin" />
</path>
<path id="r2">
<animate attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" begin="p1.begin+1s" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin+1s" />
</path>
<path id="r3">
<animate attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" begin="p1.begin+2s" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin+2s" />
</path>
<path id="r4">
<animate id="p1" attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" begin="p1.begin+3s" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin+3s" />
</path>
<path id="r5">
<animate attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" begin="p1.begin+4s" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin+4s" />
</path>
<path id="r6">
<animate attributeName="d"
values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s"
repeatCount="indefinite" begin="p1.begin+5s" />
<animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite"
begin="p1.begin+5s" />
</path>
</defs>
<use xlink:href="#r1" />
<use xlink:href="#r1" transform="rotate(60 160 160)" />
<use xlink:href="#r1" transform="rotate(120 160 160)" />
<use xlink:href="#r1" transform="rotate(180 160 160)" />
<use xlink:href="#r1" transform="rotate(240 160 160)" />
<use xlink:href="#r1" transform="rotate(300 160 160)" />
<use xlink:href="#r2" transform="rotate(30 160 160)" />
<use xlink:href="#r2" transform="rotate(90 160 160)" />
<use xlink:href="#r2" transform="rotate(150 160 160)" />
<use xlink:href="#r2" transform="rotate(210 160 160)" />
<use xlink:href="#r2" transform="rotate(270 160 160)" />
<use xlink:href="#r2" transform="rotate(330 160 160)" />
<use xlink:href="#r3" />
<use xlink:href="#r3" transform="rotate(60 160 160)" />
<use xlink:href="#r3" transform="rotate(120 160 160)" />
<use xlink:href="#r3" transform="rotate(180 160 160)" />
<use xlink:href="#r3" transform="rotate(240 160 160)" />
<use xlink:href="#r3" transform="rotate(300 160 160)" />
<use xlink:href="#r4" transform="rotate(30 160 160)" />
<use xlink:href="#r4" transform="rotate(90 160 160)" />
<use xlink:href="#r4" transform="rotate(150 160 160)" />
<use xlink:href="#r4" transform="rotate(210 160 160)" />
<use xlink:href="#r4" transform="rotate(270 160 160)" />
<use xlink:href="#r4" transform="rotate(330 160 160)" />
<use xlink:href="#r5" />
<use xlink:href="#r5" transform="rotate(60 160 160)" />
<use xlink:href="#r5" transform="rotate(120 160 160)" />
<use xlink:href="#r5" transform="rotate(180 160 160)" />
<use xlink:href="#r5" transform="rotate(240 160 160)" />
<use xlink:href="#r5" transform="rotate(300 160 160)" />
<use xlink:href="#r6" transform="rotate(30 160 160)" />
<use xlink:href="#r6" transform="rotate(90 160 160)" />
<use xlink:href="#r6" transform="rotate(150 160 160)" />
<use xlink:href="#r6" transform="rotate(210 160 160)" />
<use xlink:href="#r6" transform="rotate(270 160 160)" />
<use xlink:href="#r6" transform="rotate(330 160 160)" />
</svg>
</div>
</div><!-- end of #otherChart -->
<!--The hidden div below contains all the svg for the letters. The elements are only allowed to be paths or polygons, with no strokes used. Changing optotype colour in the config settings will only change the fill of elements which are not classed "white" below. This protects the white filled elements of vanishing optotypes-->
<div style="display:none;" id="list-character">
<!--new Snellen-->
<svg id="Snellen_A" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 5 L 1.45 0 H 2.55 L 4 5 H 2.95 L 2.65 4 H 1.3 L 1.6 3 H 2.375 L 2 1.65 L 1.05 5 H 0" fill="black"></path>
</svg>
<svg id="Snellen_D" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 1.5 A 2 2 0 0 1 1.5 5 H 0 V 1 H 1 V 4 H 1.5 A 1 1 0 0 0 1.5 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Snellen_E" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 4,0 4,1 1,1 1,2 3,2 3,3 1,3 1,4 4,4 4,5 0,5" fill="black" />
</svg>
<svg id="Snellen_F" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 4,0 4,1 1,1 1,2 3,2 3,3 1,3 1,5 0,5" fill="black" />
</svg>
<svg id="Snellen_H" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,2 3,2 3,0 4,0 4,5 3,5 3,3 1,3 1,5 0,5" fill="black" />
</svg>
<svg id="Snellen_L" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,4 4,4 4,5 0,5" fill="black" />
</svg>
<svg id="Snellen_N" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 3,3.1 3,0 4,0 4,5 3,5 1,1.9 1,5 0,5" fill="black" />
</svg>
<svg id="Snellen_P" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 2.5 A 1.5 1.5 0 0 1 2.5 3 H 1 V 5 H 0 V 1 H 1 V 2 H 2.5 A 0.5 0.5 0 0 0 2.5 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Snellen_R" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 2.5 A 1.5 1.5 0 0 1 2.5 3 L 2.9 2.8 L 4 5 H 2.8 L 1.8 3 H 1 V 5 H 0 V 1 H 1 V 2 H 2.5 A 0.5 0.5 0 0 0 2.5 1 H 0 V 0" fill="black">
</path>
</svg>
<svg id="Snellen_T" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 4,0 4,1 2.5,1 2.5,5 1.5,5 1.5,1 0,1" fill="black" />
</svg>
<svg id="Snellen_U" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 V 3 A 1.5 1.5 0 1 0 4 3 V 0 H 3 V 3 A 1 1 0 0 1 1 3 V 0 H 0" fill="black"></path>
</svg>
<svg id="Snellen_V" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1.1,0 2,3.5 2.9,0 4,0 2.6,5 1.4,5" fill="black" />
</svg>
<svg id="Snellen_X" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1.2,0 2,1.5 2.8,0 4,0 2.6,2.5 4,5 2.8,5 2,3.5 1.2,5 0,5 1.4,2.5" fill="black" />
</svg>
<svg id="Snellen_Y" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1.1,0 2,1.5 2.9,0 4,0 2.5,2.5 2.5,5 1.5,5 1.5,2.5" fill="black" />
</svg>
<svg id="Snellen_Z" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 4,0 4,1 1.4,4 4,4 4,5 0,5 0,4 2.6,1 0,1" fill="black" />
</svg>
<!--new Sloan-->
<svg id="Sloan_C" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 2 H 4 A 1.5 1.5 0 1 0 4 3 H 5 A 2.5 2.5 0 1 1 5 2" fill="black"></path>
</svg>
<svg id="Sloan_D" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 5 1.5 V 3.5 A 1.5 1.5 0 0 1 3.5 5 H 0 V 1 H 1 V 4 H 3.5 A 0.5 0.5 0 0 0 4 3.5 V 1.5 A 0.5 0.5 0 0 0 3.5 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Sloan_E" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,1 1,1 1,2 5,2 5,3 1,3 1,4 5,4 5,5 0,5" fill="black" />
</svg>
<svg id="Sloan_H" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,2 4,2 4,0 5,0 5,5 4,5 4,3 1,3 1,5 0,5" fill="black" />
</svg>
<svg id="Sloan_K" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,1.9 3.4,0 5,0 2.7,1.8 5,5 3.7,5 1.9,2.5 1,3.2 1,5 0,5" fill="black" />
</svg>
<svg id="Sloan_L" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,4 5,4 5,5 0,5" fill="black" />
</svg>
<svg id="Sloan_N" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,5 0,0 1,0 4,3.5 4,0 5,0 5,5 4,5 1,1.6 1,5" fill="black" />
</svg>
<svg id="Sloan_O" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 2.5 0 A 2.5 2.5 0 1 1 2.5 5 V 4 A 1.5 1.5 0 1 0 2.5 1 V 0" fill="black"></path>
<path d="M 2.5 0 A 2.5 2.5 0 1 0 2.5 5 V 4 A 1.5 1.5 0 1 1 2.5 1 V 0" fill="black"></path>
</svg>
<svg id="Sloan_P" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 3.5 3 H 1 V 5 H 0 V 1 H 1 V 2 H 3.5 A 0.5 0.5 0 1 0 3.5 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Sloan_R" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 3.5 3 L 5 5 H 3.8 L 2.3 3 H 1 V 5 H 0 V 1 H 1 V 2 H 3.5 A 0.5 0.5 0 1 0 3.5 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Sloan_S" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 1.5 A 1.5 1.5 0 0 0 3.5 0 H 1.5 A 1.5 1.5 0 0 0 1.5 3 H 3.5 A 0.5 0.5 0 0 1 3.5 4 H 1.5 A 0.5 0.5 0 0 1 1 3.5 H 0 A 1.5 1.5 0 0 0 1.5 5 H 3.5 A 1.5 1.5 0 1 0 3.5 2 H 1.5 A 0.5 0.5 0 1 1 1.5 1 H 3.5 A 0.5 0.5 0 0 1 4 1.5 H 5" fill="black"></path>
</svg>
<svg id="Sloan_T" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,1 3,1 3,5 2,5 2,1 0,1" fill="black" />
</svg>
<svg id="Sloan_V" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1.1,0 2.5,3.5 3.9,0 5,0 3,5 2,5" fill="black" />
</svg>
<svg id="Sloan_X" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 3.7,5 5,5 1.3,0" fill="black" />
<polygon points="0,5 3.7,0 5,0 1.3,5" fill="black" />
</svg>
<svg id="Sloan_Z" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,1 1.6,4 5,4 5,5 0,5 0,4 3.4,1 0,1" fill="black" />
</svg>
<!--LandoltC-->
<svg id="LandoltC_N" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 2 H 4 A 1.5 1.5 0 1 0 4 3 H 5 A 2.5 2.5 0 1 1 5 2" fill="black" transform="rotate (270 2.5 2.5)"></path>
</svg>
<svg id="LandoltC_E" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 2 H 4 A 1.5 1.5 0 1 0 4 3 H 5 A 2.5 2.5 0 1 1 5 2" fill="black"></path>
</svg>
<svg id="LandoltC_S" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 2 H 4 A 1.5 1.5 0 1 0 4 3 H 5 A 2.5 2.5 0 1 1 5 2" fill="black" transform="rotate (90 2.5 2.5)"></path>
</svg>
<svg id="LandoltC_W" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 5 2 H 4 A 1.5 1.5 0 1 0 4 3 H 5 A 2.5 2.5 0 1 1 5 2" fill="black" transform="rotate (180 2.5 2.5)"></path>
</svg>
<!--TumblingE-->
<svg id="TumblingE_N" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 1,0 1,4 2,4 2,0 3,0 3,4 4,4 4,0 5,0 5,5 0,5" fill="black" />
</svg>
<svg id="TumblingE_E" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,1 1,1 1,2 5,2 5,3 1,3 1,4 5,4 5,5 0,5" fill="black" />
</svg>
<svg id="TumblingE_S" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,5 4,5 4,1 3,1 3,5 2,5 2,1 1,1 1,5 0,5" fill="black" />
</svg>
<svg id="TumblingE_W" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<polygon points="0,0 5,0 5,5 0,5 0,4 4,4 4,3 0,3 0,2 4,2 4,1 0,1" fill="black" />
</svg>
<!--Vanishing Sloan-->
<svg id="VanSloan_C" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 5 2 H 4 A 1.52 1.5 0 1 0 4 3 H 4.5 V 3.25 H 4.18 A 1.78 1.75 0 1 1 4.18 1.75 H 4.69 A 2.29 2.27 0 1 0 4.69 3.25 H 4.5 V 3 H 5 A 2.52 2.5 0 1 1 5 2" fill="white" stroke="none"></path>
<path d="M 4.7 1.75 A 2.29 2.27 0 1 0 4.7 3.25 H 4.18 A 1.78 1.75 0 1 1 4.18 1.75 H 4.69" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_D" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 5 1.5 V 3.5 A 1.5 1.5 0 0 1 3.5 5 H 0 V 0.25 H 0.25 V 4.75 H 3.5 A 1.25 1.25 0 0 0 4.75 3.5 V 1.5 A 1.25 1.25 0 0 0 3.5 0.25 H 0 V 0" stroke="none" fill="white"></path>
<path class="white" d="M 0.75 0.75 H 3.5 A 0.75 0.75 0 0 1 4.25 1.5 V 3.5 A 0.75 0.75 0 0 1 3.5 4.25 H 0.75 V 1 H 1 V 4 H 3.5 A 0.5 0.5 0 0 0 4 3.5 V 1.5 A 0.5 0.5 0 0 0 3.5 1 H 0.75 V 0.75" stroke="none" fill="white"></path>
<path d="M 0.25 0.25 H 3.5 A 1.25 1.25 0 0 1 4.75 1.5 V 3.5 A 1.25 1.25 0 0 1 3.5 4.75 H 0.25 V 0.75 H 0.75 V 4.25 H 3.5 A 0.75 0.75 0 0 0 4.25 3.5 V 1.5 A 0.75 0.75 0 0 0 3.5 0.75 H 0.25 V 0.25" stroke="none" fill="black"></path>
</svg>
<svg id="VanSloan_E" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 5 V 1 H 1 V 2 H 5 V 3 H 1 V 4 H 5 V 5 H 0 V 0.25 H 0.25 V 4.75 H 4.75 V 4.25 H 0.75 V 2.75 H 4.75 V 2.25 H 0.75 V 0.75 H 4.75 V 0.25 H 0 V 0" fill="white" stroke="none"></path>
<path d="M 0.25 0.25 H 4.75 V 0.75 H 0.75 V 2.25 H 4.75 V 2.75 H 0.75 V 4.25 H 4.75 V 4.75 H 0.25 V 0.25" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_H" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0.24 0.24 H 0.76 V 2.24 H 4.24 V 0.24 H 4.76 V 4.76 H 4.24 V 2.76 H 0.76 V 4.76 H 0.24 V 0.24" fill="black" stroke="none"></path>
<path class="white" d="M 0 0 H 1 V 2 H 4 V 0 H 5 V 5 H 4 V 3 H 1 V 5 H 0 V 0.24 H 0.24 V 4.76 H 0.76 V 2.76 H 4.24 V 4.76 H 4.76 V 0.24 H 4.24 V 2.24 H 0.76 V 0.24 H 0 V 0" fill="white" stroke="none"></path>
</svg>
<svg id="VanSloan_K" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 1 V 1.9 L 3.4 0 H 5 L 2.7 1.8 L 5 5 H 3.7 L 1.9 2.5 L 1 3.2 V 5 H 0 V 0.25 H 0.25 V 4.75 H 0.75 V 3.1 L 1.92 2.18 L 3.8 4.78 H 4.6 L 2.42 1.77 L 4.4 0.22 H 3.5 L 1 2.2 H 0.75 V 0.25 H 0" fill="white" stroke="none"></path>
<path d="M 0.25 0.25 V 4.75 H 0.75 V 3.1 L 1.92 2.18 L 3.8 4.78 H 4.6 L 2.42 1.77 L 4.4 0.22 H 3.5 L 1 2.2 H 0.75 V 0.25 H 0.25" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_L" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0.25 0.25 H 0.75 V 4.25 H 4.75 V 4.75 H 0.25 V 0.25" stroke="none" fill="black"></path>
<path class="white" d="M 0 0 H 1 V 4 H 5 V 5 H 0 V 0.23 H 0.23 V 4.77 H 4.77 V 4.23 H 0.77 V 0.23 H 0 V 0" stroke="none" fill="white"></path>
</svg>
<svg id="VanSloan_N" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 1.3 L 4 3.7 V 0 H 5 V 5 H 3.7 L 1 1.3 V 5 H 0 V 0.25 H 0.25 V 4.75 H 0.75 V 0.75 H 0.92 L 3.83 4.75 H 4.75 V 0.25 H 4.25 V 4.25 H 4.07 L 1.17 0.25 H 0 V 0" stroke="none" fill="white"></path>
<path d="M 0.25 0.25 V 4.75 H 0.75 V 0.75 H 0.92 L 3.83 4.75 H 4.75 V 0.25 H 4.25 V 4.25 H 4.07 L 1.17 0.25 H 0.25" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_O" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 2.5 0 A 2.5 2.5 0 1 1 2.5 5 V 4 A 1.5 1.5 0 1 0 2.5 1 V 0" fill="white" stroke="none"></path>
<path d="M 2.5 0.25 C 5.55 0.35 5.55 4.65 2.5 4.75 V 4.25 C 4.8 4.15 4.8 0.85 2.5 0.75 V 0.25" fill="black" stroke="none"></path>
<path class="white" d="M 2.5 0 A 2.5 2.5 0 1 0 2.5 5 V 4 A 1.5 1.5 0 1 1 2.5 1 V 0" fill="white" stroke="none"></path>
<path d="M 2.5 0.25 C -0.55 0.35 -0.55 4.65 2.5 4.75 V 4.25 C 0.2 4.15 0.2 0.85 2.5 0.75 V 0.25" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_P" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 3.5 3 H 1 V 5 H 0 V 0.25 H 0.25 V 4.75 H 0.75 V 2.75 H 3.5 A 1.25 1.25 0 0 0 3.5 0.25 H 0 V 0" fill="white" stroke="none"></path>
<path d="M 0.25 0.25 H 3.5 A 1.25 1.25 0 0 1 3.5 2.75 H 0.75 V 4.74 H 0.25 V 0.75 H 0.75 V 2.25 H 3.5 A 0.75 0.75 0 0 0 3.5 0.75 H 0.25 V 0.25" fill="black" stroke="none"></path>
<path class="white" d="M 0.75 0.75 H 3.5 A 0.75 0.75 0 0 1 3.5 2.25 H 0.75 V 1 H 1 V 2 H 3.5 A 0.5 0.5 0 0 0 3.5 1 H 0.75 V 0.75" fill="white" stroke="none"></path>
</svg>
<svg id="VanSloan_R" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 3.5 A 1.5 1.5 0 0 1 3.5 3 L 5 5 H 3.7 L 2.2 3 H 1 V 5 H 0 V 0.25 H 0.25 V 4.75 H 0.75 V 2.75 H 2.35 L 3.85 4.75 H 4.5 L 3 2.75 H 3.5 A 1.25 1.25 0 0 0 3.5 0.25 H 0 V 0" fill="white" stroke="none"></path>
<path d="M 0.25 0.25 H 3.5 A 1.25 1.25 0 0 1 3.5 2.75 H 3 L 4.5 4.75 H 3.85 L 2.35 2.75 H 0.75 V 4.74 H 0.25 V 0.75 H 0.75 V 2.25 H 3.5 A 0.75 0.75 0 0 0 3.5 0.75 H 0.25 V 0.25" fill="black" stroke="none"></path>
<path class="white" d="M 0.75 0.75 H 3.5 A 0.75 0.75 0 0 1 3.5 2.25 H 0.75 V 1 H 1 V 2 H 3.5 A 0.5 0.5 0 0 0 3.5 1 H 0.75 V 0.75" fill="white" stroke="none"></path>
</svg>
<svg id="VanSloan_S" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 5 1.5 A 1.5 1.5 0 0 0 3.5 0 H 1.5 A 1.5 1.5 0 0 0 1.5 3 H 3.5 A 0.5 0.5 0 0 1 3.5 4 H 1.5 A 0.5 0.5 0 0 1 1 3.5 H 0 A 1.5 1.5 0 0 0 1.5 5 H 3.5 A 1.5 1.5 0 1 0 3.5 2 H 1.5 A 0.5 0.5 0 1 1 1.5 1 H 3.5 A 0.5 0.5 0 0 1 4 1.5 H 4.25 V 1.25 A 0.75 0.75 0 0 0 3.5 0.75 H 1.5 A 0.75 0.75 0 0 0 1.5 2.25 H 3.5 A 1.25 1.25 0 0 1 3.5 4.75 H 1.5 A 1.25 1.25 0 0 1 0.25 3.75 H 0.75 A 0.75 0.75 0 0 0 1.5 4.25 H 3.5 A 0.75 0.75 0 0 0 3.5 2.75 H 1.5 A 1.25 1.25 0 0 1 1.5 0.25 H 3.5 A 1.25 1.25 0 0 1 4.75 1.25 H 4.25 V 1.5 H 5" fill="white" stroke="none"></path>
<path d="M4.75 1.25 A 1.25 1.25 0 0 0 3.5 0.25 H 1.5 A 1.25 1.25 0 0 0 1.5 2.75 H 3.5 A 0.75 0.75 0 0 1 3.5 4.25 H 1.5 A 0.75 0.75 0 0 1 0.75 3.75 H 0.25 A 1.25 1.25 0 0 0 1.5 4.75 H 3.5 A 1.25 1.25 0 1 0 3.5 2.25 H 1.5 A 0.75 0.75 0 1 1 1.5 0.75 H 3.5 A 0.75 0.75 0 0 1 4.25 1.25 H 4.75" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_T" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0.25 0.25 H 4.75 V 0.75 H 2.75 V 4.75 H 2.25 V 0.75 H 0.25 V 0.25" fill="black" stroke="none"></path>
<path class="white" d="M 0 0 H 5 V 1 H 3 V 5 H 2 V 1 H 0 V 0.24 H 0.24 V 0.76 H 2.24 V 4.76 H 2.76 V 0.76 H 4.76 V 0.24 H 0 V 0" fill="white" stroke="none"></path>
</svg>
<svg id="VanSloan_V" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 1.1 L 2.5 3.5 L 3.9 0 H 5 L 3 5 H 2 L 0.1 0.25 H 0.35 L 2.15 4.75 H 2.85 L 4.65 0.25 H 4.05 L 2.5 4.1 L 0.95 0.25 H 0.1 L 0 0" fill="white" stroke="none"></path>
<path d="M 0.35 0.25 H 0.95 L 2.5 4.1 L 4.05 0.25 H 4.65 L 2.85 4.75 H 2.15 L 0.35 0.25" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_X" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 1.3 L 2.5 1.62 L 3.7 0 H 5 L 3.15 2.5 L 5 5 H 3.7 L 2.5 3.38 L 1.3 5 H 0 L 1.85 2.5 L 0 0" fill="white" stroke="none"></path>
<path d="M 0.43 0.22 H 1.18 L 2.5 1.97 L 3.82 0.22 H 4.57 L 2.87 2.5 L 4.57 4.78 H 3.82 L 2.5 3.03 L 1.18 4.78 H 0.43 L 2.13 2.5 L 0.43 0.22" fill="black" stroke="none"></path>
</svg>
<svg id="VanSloan_Z" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path class="white" d="M 0 0 H 5 V 1 L 1.7 4 H 5 V 5 H 0 V 4 L 3.4 1 H 0 V 0.23 H 0.23 V 0.77 H 4 L 0.23 4.1 V 4.77 H 4.77 V 4.23 H 1.05 L 4.77 0.9 V 0.23 H 0 V 0" fill="white" stroke="none"></path>
<path d="M 0.23 0.23 H 4.77 V 0.9 L 1.05 4.23 H 4.77 V 4.77 H 0.23 V 4.1 L 4 0.77 H 0.23 V 0.23" fill="black" stroke="none"></path>
</svg>
<!--new Shapes 5x5-->
<svg id="Shape5_0" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H3V2H5V3H3V5H2V3H0V2H2z" fill="black" stroke="none"></path>
</svg>
<svg id="Shape5_M" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 2H5V3H3.2L4.5 5H3.3L2.5 3.8L1.7 5H0.5L1.8 3H0z" fill="black"></path>
<circle cx="2.5" cy="1" r="1" fill="black" stroke="none"></circle>
</svg>
<svg id="Shape5_1" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 0H5V5H0V1H1V4H4V1H0z" fill="black" stroke="none"></path>
</svg>
<svg id="Shape5_2" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 5L2.5 0L5 5H3.7L2.5 2.5L1.3 5z" fill="black" stroke="none"></path>
</svg>
<svg id="Shape5_3" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M2.5 0 A 2.5 2.5 0 0 1 2.5 5 V 4 A 1.5 1.5 0 0 0 2.5 1 A 1.5 1.5 0 0 0 2.5 4 V 5 A 2.5 2.5 0 0 1 2.5 0" fill="black" stroke="none"></path>
</svg>
<svg id="Shape5_4" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H3V2L2.5 2.5L2 2zz" fill="black" stroke="none"></path>
<path d="M2 0H3V2L2.5 2.5L2 2zz" fill="black" stroke="none" transform="rotate(72,2.5,2.5)"></path>
<path d="M2 0H3V2L2.5 2.5L2 2zz" fill="black" stroke="none" transform="rotate(144,2.5,2.5)"></path>
<path d="M2 0H3V2L2.5 2.5L2 2zz" fill="black" stroke="none" transform="rotate(216,2.5,2.5)"></path>
<path d="M2 0H3V2L2.5 2.5L2 2zz" fill="black" stroke="none" transform="rotate(288,2.5,2.5)"></path>
</svg>
<!-- Chinese01 - experimental -->
<svg id="Chinese01_0" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 0H5V1H2.25L2.1 2H4.5V4H5V5H3.5V3H1.9L1.5 4H3.5V5H0V4H0.5L0.9 3H0.5V2H1.1L1.25 1H0V0z" fill="black"></path>
</svg>
<svg id="Chinese01_1" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H3V1H5V4H3V3H4V2H3V5H2V4H0V1H2V2H1V3H2V0z" fill="black"></path>
</svg>
<svg id="Chinese01_2" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M1 0H2V1H5V2H2V4H4V3H5V5H1V2H0V1H1V0z" fill="black"></path>
</svg>
<svg id="Chinese01_3" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 0H5V2H4V1H1V2H5V5H0V3H1V4H4V3H0V0z" fill="black"></path>
</svg>
<svg id="Chinese01_4" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 1H1.9L2 0H3L3.1 1H5V2H3.4C3.8 3 4.2 4 5 5H3.8C3.2 4 2.8 3.3 2.5 2.3C2.2 3.3 1.8 4 1.2 5H0C0.8 4 1.2 3 1.6 2H0V1z" fill="black"></path>
</svg>
<svg id="Chinese01_5" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0.5 0H4.5V1H0.5V0zM0.5 2H4.5V3H0.5V2zM0 4H5V5H0V4z" fill="black"></path>
</svg>
<svg id="Chinese01_6" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H3V1H5V2H3V4H5V5H0V4H2V0z" fill="black"></path>
</svg>
<svg id="Chinese01_7" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,6,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M1 0H2V5H0V4H1V0zM3 0H4V4H3V0zM5 0H6V5H5V0z" fill="black"></path>
</svg>
<svg id="Chinese01_8" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0.5 0H4.5V1H3V4H5V5H0V4H2V1H0.5V0z" fill="black"></path>
</svg>
<svg id="Chinese01_9" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 1H2.1L2.2 0H3.2L3.1 1H4A1 1 0 0 1 5 2V4A1 1 0 0 1 4 5H3V4H3.75A0.25 0.25 0 0 0 4 3.75V2.25A0.25 0.25 0 0 0 3.75 2H2.9C2.55 3 1.9 4 1.2 5H0C0.8 4 1.4 3 1.9 2H0V1z" fill="black"></path>
</svg>
<!-- Arabic - experimental - thanks to Alice Kswani -->
<svg id="Arabic01_0" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M1 0H3V1H2V2H3V3H0V2H1V0zM4 0H5V5H0V4H4V0z" fill="black"></path>
</svg>
<svg id="Arabic01_1" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M0 1H1V4H4V3H2V0H5V1H3V2H5V5H0V1z" fill="black"></path>
</svg>
<svg id="Arabic01_2" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M0 2H1V4H4V2H5V5H0V2zM1 0H2V1H1V0M3 0H4V1H3V0z" fill="black"></path>
</svg>
<svg id="Arabic01_3" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M2 0H5V5H0V4H4V3H2V1H3V2H4V1H2V0z" fill="black"></path>
</svg>
<svg id="Arabic01_4" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M0 2H1V4H4V0H5V5H0V2z" fill="black"></path>
</svg>
<svg id="Arabic01_5" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M0 0H1V2H4V0H5V3H0V0zM2 4H3V5H2V4z" fill="black"></path>
</svg>
<svg id="Arabic01_6" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M0 0H5V1H2.5C1 3 1 4 2 4H5V5H1.5C-0.25 5 -0.25 3 1.25 1H0V0z" fill="black"></path>
</svg>
<svg id="Arabic01_7" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M1 0H2A3 3 0 0 1 5 3V5H0V4H4V3.5A2.5 2.5 0 0 0 1.5 1H1V0z" fill="black"></path>
</svg>
<svg id="Arabic01_8" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M1 0H2V2H5V5H2V4H4V3H2V5H0V4H1V0z" fill="black"></path>
</svg>
<svg id="Arabic01_9" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm"
style="margin: 3.49mm;">
<path d="M2 0H5V1H3V2H4V3H1V4H5V5H0V2H2V0z" fill="black"></path>
</svg>
<!-- Hebrew01 -->
<svg id="Hebrew01_0" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 0 V2 C 0 5.8 4.6 5.78 4.8 3 L5 0 H 4 L3.8 3 C 3.55 4.5 1.4 4.1 1.2 3 Q 2.8 3 2.9 2 L 3 0 H 2 L 1.9 1.5 Q 1.8 2.1 1 2 V 0 H 0" fill="black"></path>
</svg>
<svg id="Hebrew01_1" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M0 0H 1.1 L2.15 2.55C2.6 2 2.8 1.5 2.95 0L4 0.2C3.8 2.5 3 4 0.2 5L0 3.95C0.5 3.7 0.7 3.7 1.3 3.3L0 0z" fill="black"></path>
</svg>
<svg id="Hebrew01_2" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 3 Q 4.9 0 5 2.5 V 5 5 H 4 V 3.5 Q 4.15 0.9 2.5 1 H 2 V 4 Q 2 4.9 1 5 H 0 V 4 Q 1.05 4.1 1 3.5 V 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Hebrew01_3" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0.25 C 5.3 -1.4 5.3 6.4 0 4.75 V 3.75 C 4 5.4 3.7 0 0.9 0.9 V 1.5 Q 0.9 2.4 1.5 2.2 V 3.1 Q 0.1 3.3 0 1.5 V 0.25" fill="black"></path>
</svg>
<svg id="Hebrew01_4" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 1.1 L 2.3 2.1 Q 3.1 1.8 3 0 H 4 Q 4.1 2.2 2.8 3 L 4 5 H 2.9 L 1.35 2.3 Q 1.1 2.4 1.1 3 L 1 5 H 0 Q 0 1.8 0.8 1.4 L 0 0" fill="black"></path>
</svg>
<svg id="Hebrew01_5" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,3.5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0.5 0 H 1.5 Q 2.9 0.2 3 1.5 V 3.5 L 3.5 5 H 2.5 L 2.1 3.8 Q 1 3.7 1 5 H 0 Q 0 3 2 2.85 V 2 Q 2 1 1 1 H 0.5 V 0" fill="black"></path>
</svg>
<svg id="Hebrew01_6" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0.25 C 5.3 -1.4 5.3 6.4 0 4.75 V 3.75 C 4 5.4 4 -0.4 0 1.25 V 0.25" fill="black"></path>
</svg>
<svg id="Hebrew01_7" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 L 2.8 4 H 0 V 5 H 4 V 3.9 L 2.9 2.4 Q 4 2 4 1 V 0 H 3 V 0.5 Q 3 1.4 2.4 1.7 L 1.2 0 H 0" fill="black"></path>
</svg>
<svg id="Hebrew01_8" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 4 V 1 H 3 V 5 H 2 V 1 H 0 V 0" fill="black"></path>
</svg>
<svg id="Hebrew01_9" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<path d="M 0 0 H 2 Q 4 0 4 2 V 4 H 5 V 5 H 0 V 4 H 3 V 2.5 Q 3 1.1 2 1 H 0 V 0" fill="black"></path>
</svg>
<!-- Crowded HOTV -->
<svg id="CrowdedHOTV01_0" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,8,9" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H6V1H2V0zM7 2H8V7H7V2zM2 8H6V9H2V8zM0 2H1V7H0V2z" fill="black"></path>
<path d="M2 2H3V4H5V2H6V7H5V5H3V7H2V2z" fill="black"></path>
</svg>
<svg id="CrowdedHOTV01_1" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,9,9" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H7V1H2V0zM8 2H9V7H8V2zM2 8H7V9H2V8zM0 2H1V7H0V2z" fill="black"></path>
<path d="M4.5 2A2.5 2.5 0 1 1 4.5 7V6A1.5 1.5 0 1 0 4.5 3V2z" fill="black"></path>
<path d="M4.5 2A2.5 2.5 0 1 0 4.5 7V6A1.5 1.5 0 1 1 4.5 3V2z" fill="black"></path>
</svg>
<svg id="CrowdedHOTV01_2" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,8,9" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H6V1H2V0zM7 2H8V7H7V2zM2 8H6V9H2V8zM0 2H1V7H0V2z" fill="black"></path>
<path d="M2 2H6V3H4.5V7H3.5V3H2V2z" fill="black"></path>
</svg>
<svg id="CrowdedHOTV01_3" class="optotype-symbol" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,8,9" height="8.73mm" style="margin: 3.49mm;">
<path d="M2 0H6V1H2V0zM7 2H8V7H7V2zM2 8H6V9H2V8zM0 2H1V7H0V2z" fill="black"></path>
<path d="M2 2H3.1L4 5.2L4.9 2H6L4.5 7H3.5L2 2z" fill="black"></path>
</svg>
<!-- end of optotype svgs -->
<!-- other letter chart furniture-->
<!-- guides for 6/12 and 6/6 --->
<svg id="red_rect" class="guide-dot" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<rect x="0" cy="0" width="5" height="5" fill="rgba(255,0,0,1)" stroke="none" />
</svg>
<svg id="green_dot" class="guide-dot" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,5,5" height="8.73mm" style="margin: 3.49mm;">
<circle cx="2.5" cy="2.5" r="2.5" fill="rgba(0,200,127,1)" stroke="none" />
</svg>
<!-- arrows and buttons for navigation -->
<div id="buttons">
<svg class="arrow-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible">
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(102,102,102)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<path class="arrow" d="M1.5 0.5L3.5 2L1.5 3.5L1.1 3.3L2.3 2L1.1 0.7z" fill="rgb(255,255,255)" stroke-width="0" />
</svg>
<svg class="up-arrow-prototype" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 5 7"
width="200px" >
<defs>
<mask id="up-arrow-mask0">
<path d="M2.5 0.2H4.6A0.2 0.2 0 0 1 4.8 0.4V3.65A0.4 0.4 0 0 1 4.6 4L2.5 5L0.4 4A0.4 0.4 0 0 1 0.2 3.65V0.4A0.2 0.2 0 0 1 0.4 0.2H2.5z" transform="translate(0.125,0.125) scale(0.95,0.95)" fill="rgb(255,255,255)" stroke="none"></path>
</mask>
</defs>
<g class="up-arrow-g0">
<path d="M2.5 0.2H4.6A0.2 0.2 0 0 1 4.8 0.4V3.65A0.4 0.4 0 0 1 4.6 4L2.5 5L0.4 4A0.4 0.4 0 0 1 0.2 3.65V0.4A0.2 0.2 0 0 1 0.4 0.2H2.5z" fill="rgb(255,255,255)" stroke-width="0.16" stroke="rgb(128,128,128)" ></path>
</g>
<g class="up-arrow-g1" mask="url(#up-arrow-mask0)"></g>
<g class="up-arrow-g2" transform="scale(1.25,1.25) translate(-0.5,-0.5)">
<circle class='arrow-active' cx='2.5' cy='4.2' r='1.5' fill="transparent" stroke-width="0.2" stroke="rgb(102,102,102)" />
<circle class="arrow-dot" cx="2.5" cy="4.2" r="1.2" fill="rgb(102,102,102)" stroke-width="0.067" stroke="rgb(152,152,152)"/>
<path class="arrow" d="M2.5 3.25L3.45 4.5L3.3 4.75L2.5 4L1.7 4.75L1.55 4.5z" fill="rgb(255,255,255)" stroke-width="0" />
</g>
</svg>
<svg class="dn-arrow-prototype" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 5 7"
width="200px" >
<defs>
<mask id="dn-arrow-mask0">
<path d="M2.5 6.8H0.4A0.2 0.2 0 0 1 0.2 6.6V3.35A0.4 0.4 0 0 1 0.4 3L2.5 2L4.6 3A0.4 0.4 0 0 1 4.8 3.35V6.6A0.2 0.2 0 0 1 4.6 6.8H2.5z" transform="translate(0.125,0.25) scale(0.95,0.95)" fill="rgb(255,255,255)" stroke="none" ></path>
</mask>
</defs>
<g class="dn-arrow-g0">
<path d="M2.5 6.8H0.4A0.2 0.2 0 0 1 0.2 6.6V3.35A0.4 0.4 0 0 1 0.4 3L2.5 2L4.6 3A0.4 0.4 0 0 1 4.8 3.35V6.6A0.2 0.2 0 0 1 4.6 6.8H2.5z" fill="rgb(255,255,255)" stroke-width="0.16" stroke="rgb(128,128,128)" ></path>
</g>
<g class="dn-arrow-g1" mask="url(#dn-arrow-mask0)" ></g>
<g class="dn-arrow-g2" transform="scale(1.25,1.25) translate(-0.5,-2.5) rotate(180,2.5,4.2)">
<circle class='arrow-active' cx='2.5' cy='4.2' r='1.5' fill="transparent" stroke-width="0.2" stroke="rgb(102,102,102)" />
<circle class="arrow-dot" cx="2.5" cy="4.2" r="1.2" fill="rgb(102,102,102)" stroke-width="0.067" stroke="rgb(152,152,152)"/>
<path class="arrow" d="M2.5 3.25L3.45 4.5L3.3 4.75L2.5 4L1.7 4.75L1.55 4.5z" fill="rgb(255,255,255)" stroke-width="0" />
</g>
</svg>
<svg class="bg-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible" width="200px">
<defs>
<linearGradient id="bg-grad0" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="50%" style="stop-color:rgb(0,200,127);stop-opacity:1" />
<stop offset="50%" style="stop-color:rgb(225,0,0);stop-opacity:1" />
</linearGradient>
</defs>
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<g id="bg-button-duo">
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="url(#bg-grad0)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<path d="M0 0H4V1H1V2H4V3H1V4H4V5H0z" transform="translate(1,0.75) scale(0.5,0.5)" fill="rgb(0,0,0)"></path>
</g>
<g id="bg-button-white" display="none">
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(255,255,255)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<path d="M0 0H4V1H1V2H4V3H1V4H4V5H0z" transform="translate(1,0.75) scale(0.5,0.5)" fill="rgb(0,0,0)"></path>
</g>
</svg>
<svg class="shuffle-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible" width="200px">
<defs>
<path id="path-shuffle-arrow" d="M0.5 1.2L1.1 0.7L1.2 0.8L1.1 1A1.4 1.4 0 0 1 2.2 1.9L2.1 2.1L1.8 2.1A1.1 1.1 0 0 0 1.1 1.4L1.2 1.6L1.1 1.7z"></path>
</defs>
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(102,102,102)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<g id="shuffle-button-shuffle">
<use xlink:href="#path-shuffle-arrow" fill="rgb(152,152,152)" stroke="none" />
<use xlink:href="#path-shuffle-arrow" transform="rotate(180,2,2)" fill="rgb(152,152,152)" stroke="none" />
<rect x="1.5" y="1.6" width="1" height="0.8" transform="rotate(-60,2,2)" fill="rgb(102,102,102)" stroke="none"></rect>
<use xlink:href="#path-shuffle-arrow" transform="scale(-1,1) translate(-4,0) rotate(180,2,2)" fill="rgb(152,152,152)" />
<use xlink:href="#path-shuffle-arrow" transform="scale(-1,1) translate(-4,0)" fill="rgb(152,152,152)" />
</g>
<g id="shuffle-button-unshuffle" display="none">
<use xlink:href="#path-shuffle-arrow" fill="rgb(0,200,127)" stroke="none" />
<use xlink:href="#path-shuffle-arrow" transform="rotate(180,2,2)" fill="rgb(0,200,127)" stroke="none" />
<rect x="1.5" y="1.6" width="1" height="0.8" transform="rotate(-60,2,2)" fill="rgb(102,102,102)" stroke="none"></rect>
<use xlink:href="#path-shuffle-arrow" transform="scale(-1,1) translate(-4,0) rotate(180,2,2)" fill="rgb(0,200,127)" />
<use xlink:href="#path-shuffle-arrow" transform="scale(-1,1) translate(-4,0)" fill="rgb(0,200,127)" />
</g>
</svg>
<svg class="zoom-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible" width="200px">
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(102,102,102)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<circle cx="1.6" cy="1.6" r="0.9" fill="none" stroke-width="0.2" stroke="rgb(255,255,255)"></circle>
<path d="M2 0L2.2 0.2V1.2H1.8V0.2L2 0z" fill="rgb(255,255,255)" stroke="none" transform="translate(0.75,2.05) rotate(-45,2,0.7)"></path>
<g id="zoom-button-plus">
<path d="M1 1.6H2.2M1.6 1V2.2" fill="none" stroke-width="0.3" stroke="rgb(255,255,255)"></path>
</g>
<g id="zoom-button-minus" display="none">
<path d="M1 1.6H2.2" fill="none" stroke-width="0.3" stroke="rgb(255,255,255)"></path>
</g>
</svg>
<svg class="rotate-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible" width="200px">
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(102,102,102)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<g id="rotate-button-cw" >
<path d="M2 0.5A1.5 1.5 0 0 1 3.5 2L3.7 1.9L3.8 2L3.25 2.6L2.7 2L2.8 1.9L3 2A1 1 0 0 0 2 1V1z" transform="rotate(-22,2,2)" fill="rgb(255,255,255)"></path>
<path d="M2 0.5A1.5 1.5 0 0 1 3.5 2L3.7 1.9L3.8 2L3.25 2.6L2.7 2L2.8 1.9L3 2A1 1 0 0 0 2 1V1z" transform="rotate(158,2,2)" fill="rgb(255,255,255)"></path>
</g>
<g id="rotate-button-ccw" transform="scale(-1,1) translate(-4,0)" display="none">
<path d="M2 0.5A1.5 1.5 0 0 1 3.5 2L3.7 1.9L3.8 2L3.25 2.6L2.7 2L2.8 1.9L3 2A1 1 0 0 0 2 1V1z" transform="rotate(-22,2,2)" fill="rgb(255,255,255)"></path>
<path d="M2 0.5A1.5 1.5 0 0 1 3.5 2L3.7 1.9L3.8 2L3.25 2.6L2.7 2L2.8 1.9L3 2A1 1 0 0 0 2 1V1z" transform="rotate(158,2,2)" fill="rgb(255,255,255)"></path>
</g>
</svg>
<svg class="interspace-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible" width="200px">
<defs>
<path id="path-interspace-arrow" d="M0.4 2L1 1.5L1.1 1.6L1 1.8H2.1V2.2H1L1.1 2.4L1 2.5z"></path>
</defs>
<circle class='arrow-active' cx='2' cy='2' r='2.4' fill="transparent" stroke-width="0.3" stroke="rgb(102,102,102)"/>
<circle class="arrow-dot" cx="2" cy="2" r="2" fill="rgb(102,102,102)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<g id="interspace-button-off">
<use xlink:href="#path-interspace-arrow" fill="rgb(152,152,152)" stroke="none" />
<use xlink:href="#path-interspace-arrow" transform="rotate(180,2,2)" fill="rgb(152,152,152)" stroke="none" />
</g>
<g id="interspace-button-on" display="none">
<use xlink:href="#path-interspace-arrow" fill="rgb(0,200,127)" stroke="none" />
<use xlink:href="#path-interspace-arrow" transform="rotate(180,2,2)" fill="rgb(0,200,127)" stroke="none" />
</g>
</svg>
<svg class="nav-button-prototype" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,4,4" overflow="visible">
<circle class='dot-active' cx='2' cy='2' r='2.4' fill='transparent' stroke-width='0.3' stroke='rgb(102,102,102)'/>
<circle class="dot" cx="2" cy="2" r="2" fill="rgb(174,39,96)" stroke-width="0.1" stroke="rgb(152,152,152)"/>
<text class="dot-text" x="50%" y="50%" font-size="3" font-weight="bold" text-anchor="middle" dy="0.35em" fill="rgb(255,255,255)">?</text>
</svg>
</div>
</div>
<!-- end of hidden div of svg elements-->
<div class="mask"></div>
<div class="IENotice">
<div class="modal">Your browser is not supported. You can download the latest version <a href="https://www.microsoft.com/en-us/download/internet-explorer.aspx">here </a></div>
</div>
<script type="text/javascript">
/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */
!function (a, b) { "use strict"; "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function (a) { if (!a.document) throw new Error("jQuery requires a window with a document"); return b(a) } : b(a) }("undefined" != typeof window ? window : this, function (a, b) {
"use strict"; var c = [], d = a.document, e = Object.getPrototypeOf, f = c.slice, g = c.concat, h = c.push, i = c.indexOf, j = {}, k = j.toString, l = j.hasOwnProperty, m = l.toString, n = m.call(Object), o = {}; function p(a, b) { b = b || d; var c = b.createElement("script"); c.text = a, b.head.appendChild(c).parentNode.removeChild(c) } var q = "3.1.1", r = function (a, b) { return new r.fn.init(a, b) }, s = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, t = /^-ms-/, u = /-([a-z])/g, v = function (a, b) { return b.toUpperCase() }; r.fn = r.prototype = { jquery: q, constructor: r, length: 0, toArray: function () { return f.call(this) }, get: function (a) { return null == a ? f.call(this) : a < 0 ? this[a + this.length] : this[a] }, pushStack: function (a) { var b = r.merge(this.constructor(), a); return b.prevObject = this, b }, each: function (a) { return r.each(this, a) }, map: function (a) { return this.pushStack(r.map(this, function (b, c) { return a.call(b, c, b) })) }, slice: function () { return this.pushStack(f.apply(this, arguments)) }, first: function () { return this.eq(0) }, last: function () { return this.eq(-1) }, eq: function (a) { var b = this.length, c = +a + (a < 0 ? b : 0); return this.pushStack(c >= 0 && c < b ? [this[c]] : []) }, end: function () { return this.prevObject || this.constructor() }, push: h, sort: c.sort, splice: c.splice }, r.extend = r.fn.extend = function () { var a, b, c, d, e, f, g = arguments[0] || {}, h = 1, i = arguments.length, j = !1; for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || r.isFunction(g) || (g = {}), h === i && (g = this, h--) ; h < i; h++) if (null != (a = arguments[h])) for (b in a) c = g[b], d = a[b], g !== d && (j && d && (r.isPlainObject(d) || (e = r.isArray(d))) ? (e ? (e = !1, f = c && r.isArray(c) ? c : []) : f = c && r.isPlainObject(c) ? c : {}, g[b] = r.extend(j, f, d)) : void 0 !== d && (g[b] = d)); return g }, r.extend({ expando: "jQuery" + (q + Math.random()).replace(/\D/g, ""), isReady: !0, error: function (a) { throw new Error(a) }, noop: function () { }, isFunction: function (a) { return "function" === r.type(a) }, isArray: Array.isArray, isWindow: function (a) { return null != a && a === a.window }, isNumeric: function (a) { var b = r.type(a); return ("number" === b || "string" === b) && !isNaN(a - parseFloat(a)) }, isPlainObject: function (a) { var b, c; return !(!a || "[object Object]" !== k.call(a)) && (!(b = e(a)) || (c = l.call(b, "constructor") && b.constructor, "function" == typeof c && m.call(c) === n)) }, isEmptyObject: function (a) { var b; for (b in a) return !1; return !0 }, type: function (a) { return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? j[k.call(a)] || "object" : typeof a }, globalEval: function (a) { p(a) }, camelCase: function (a) { return a.replace(t, "ms-").replace(u, v) }, nodeName: function (a, b) { return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase() }, each: function (a, b) { var c, d = 0; if (w(a)) { for (c = a.length; d < c; d++) if (b.call(a[d], d, a[d]) === !1) break } else for (d in a) if (b.call(a[d], d, a[d]) === !1) break; return a }, trim: function (a) { return null == a ? "" : (a + "").replace(s, "") }, makeArray: function (a, b) { var c = b || []; return null != a && (w(Object(a)) ? r.merge(c, "string" == typeof a ? [a] : a) : h.call(c, a)), c }, inArray: function (a, b, c) { return null == b ? -1 : i.call(b, a, c) }, merge: function (a, b) { for (var c = +b.length, d = 0, e = a.length; d < c; d++) a[e++] = b[d]; return a.length = e, a }, grep: function (a, b, c) { for (var d, e = [], f = 0, g = a.length, h = !c; f < g; f++) d = !b(a[f], f), d !== h && e.push(a[f]); return e }, map: function (a, b, c) { var d, e, f = 0, h = []; if (w(a)) for (d = a.length; f < d; f++) e = b(a[f], f, c), null != e && h.push(e); else for (f in a) e = b(a[f], f, c), null != e && h.push(e); return g.apply([], h) }, guid: 1, proxy: function (a, b) { var c, d, e; if ("string" == typeof b && (c = a[b], b = a, a = c), r.isFunction(a)) return d = f.call(arguments, 2), e = function () { return a.apply(b || this, d.concat(f.call(arguments))) }, e.guid = a.guid = a.guid || r.guid++, e }, now: Date.now, support: o }), "function" == typeof Symbol && (r.fn[Symbol.iterator] = c[Symbol.iterator]), r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (a, b) { j["[object " + b + "]"] = b.toLowerCase() }); function w(a) { var b = !!a && "length" in a && a.length, c = r.type(a); return "function" !== c && !r.isWindow(a) && ("array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a) } var x = function (a) { var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + 1 * new Date, v = a.document, w = 0, x = 0, y = ha(), z = ha(), A = ha(), B = function (a, b) { return a === b && (l = !0), 0 }, C = {}.hasOwnProperty, D = [], E = D.pop, F = D.push, G = D.push, H = D.slice, I = function (a, b) { for (var c = 0, d = a.length; c < d; c++) if (a[c] === b) return c; return -1 }, J = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", K = "[\\x20\\t\\r\\n\\f]", L = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", M = "\\[" + K + "*(" + L + ")(?:" + K + "*([*^$|!~]?=)" + K + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + L + "))|)" + K + "*\\]", N = ":(" + L + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + M + ")*)|.*)\\)|)", O = new RegExp(K + "+", "g"), P = new RegExp("^" + K + "+|((?:^|[^\\\\])(?:\\\\.)*)" + K + "+$", "g"), Q = new RegExp("^" + K + "*," + K + "*"), R = new RegExp("^" + K + "*([>+~]|" + K + ")" + K + "*"), S = new RegExp("=" + K + "*([^\\]'\"]*?)" + K + "*\\]", "g"), T = new RegExp(N), U = new RegExp("^" + L + "$"), V = { ID: new RegExp("^#(" + L + ")"), CLASS: new RegExp("^\\.(" + L + ")"), TAG: new RegExp("^(" + L + "|[*])"), ATTR: new RegExp("^" + M), PSEUDO: new RegExp("^" + N), CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + K + "*(even|odd|(([+-]|)(\\d*)n|)" + K + "*(?:([+-]|)" + K + "*(\\d+)|))" + K + "*\\)|)", "i"), bool: new RegExp("^(?:" + J + ")$", "i"), needsContext: new RegExp("^" + K + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + K + "*((?:-\\d)?\\d*)" + K + "*\\)|)(?=[^-]|$)", "i") }, W = /^(?:input|select|textarea|button)$/i, X = /^h\d$/i, Y = /^[^{]+\{\s*\[native \w/, Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, $ = /[+~]/, _ = new RegExp("\\\\([\\da-f]{1,6}" + K + "?|(" + K + ")|.)", "ig"), aa = function (a, b, c) { var d = "0x" + b - 65536; return d !== d || c ? b : d < 0 ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320) }, ba = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, ca = function (a, b) { return b ? "\0" === a ? "\ufffd" : a.slice(0, -1) + "\\" + a.charCodeAt(a.length - 1).toString(16) + " " : "\\" + a }, da = function () { m() }, ea = ta(function (a) { return a.disabled === !0 && ("form" in a || "label" in a) }, { dir: "parentNode", next: "legend" }); try { G.apply(D = H.call(v.childNodes), v.childNodes), D[v.childNodes.length].nodeType } catch (fa) { G = { apply: D.length ? function (a, b) { F.apply(a, H.call(b)) } : function (a, b) { var c = a.length, d = 0; while (a[c++] = b[d++]); a.length = c - 1 } } } function ga(a, b, d, e) { var f, h, j, k, l, o, r, s = b && b.ownerDocument, w = b ? b.nodeType : 9; if (d = d || [], "string" != typeof a || !a || 1 !== w && 9 !== w && 11 !== w) return d; if (!e && ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, p)) { if (11 !== w && (l = Z.exec(a))) if (f = l[1]) { if (9 === w) { if (!(j = b.getElementById(f))) return d; if (j.id === f) return d.push(j), d } else if (s && (j = s.getElementById(f)) && t(b, j) && j.id === f) return d.push(j), d } else { if (l[2]) return G.apply(d, b.getElementsByTagName(a)), d; if ((f = l[3]) && c.getElementsByClassName && b.getElementsByClassName) return G.apply(d, b.getElementsByClassName(f)), d } if (c.qsa && !A[a + " "] && (!q || !q.test(a))) { if (1 !== w) s = b, r = a; else if ("object" !== b.nodeName.toLowerCase()) { (k = b.getAttribute("id")) ? k = k.replace(ba, ca) : b.setAttribute("id", k = u), o = g(a), h = o.length; while (h--) o[h] = "#" + k + " " + sa(o[h]); r = o.join(","), s = $.test(a) && qa(b.parentNode) || b } if (r) try { return G.apply(d, s.querySelectorAll(r)), d } catch (x) { } finally { k === u && b.removeAttribute("id") } } } return i(a.replace(P, "$1"), b, d, e) } function ha() { var a = []; function b(c, e) { return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e } return b } function ia(a) { return a[u] = !0, a } function ja(a) { var b = n.createElement("fieldset"); try { return !!a(b) } catch (c) { return !1 } finally { b.parentNode && b.parentNode.removeChild(b), b = null } } function ka(a, b) { var c = a.split("|"), e = c.length; while (e--) d.attrHandle[c[e]] = b } function la(a, b) { var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && a.sourceIndex - b.sourceIndex; if (d) return d; if (c) while (c = c.nextSibling) if (c === b) return -1; return a ? 1 : -1 } function ma(a) { return function (b) { var c = b.nodeName.toLowerCase(); return "input" === c && b.type === a } } function na(a) { return function (b) { var c = b.nodeName.toLowerCase(); return ("input" === c || "button" === c) && b.type === a } } function oa(a) { return function (b) { return "form" in b ? b.parentNode && b.disabled === !1 ? "label" in b ? "label" in b.parentNode ? b.parentNode.disabled === a : b.disabled === a : b.isDisabled === a || b.isDisabled !== !a && ea(b) === a : b.disabled === a : "label" in b && b.disabled === a } } function pa(a) { return ia(function (b) { return b = +b, ia(function (c, d) { var e, f = a([], c.length, b), g = f.length; while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e])) }) }) } function qa(a) { return a && "undefined" != typeof a.getElementsByTagName && a } c = ga.support = {}, f = ga.isXML = function (a) { var b = a && (a.ownerDocument || a).documentElement; return !!b && "HTML" !== b.nodeName }, m = ga.setDocument = function (a) { var b, e, g = a ? a.ownerDocument || a : v; return g !== n && 9 === g.nodeType && g.documentElement ? (n = g, o = n.documentElement, p = !f(n), v !== n && (e = n.defaultView) && e.top !== e && (e.addEventListener ? e.addEventListener("unload", da, !1) : e.attachEvent && e.attachEvent("onunload", da)), c.attributes = ja(function (a) { return a.className = "i", !a.getAttribute("className") }), c.getElementsByTagName = ja(function (a) { return a.appendChild(n.createComment("")), !a.getElementsByTagName("*").length }), c.getElementsByClassName = Y.test(n.getElementsByClassName), c.getById = ja(function (a) { return o.appendChild(a).id = u, !n.getElementsByName || !n.getElementsByName(u).length }), c.getById ? (d.filter.ID = function (a) { var b = a.replace(_, aa); return function (a) { return a.getAttribute("id") === b } }, d.find.ID = function (a, b) { if ("undefined" != typeof b.getElementById && p) { var c = b.getElementById(a); return c ? [c] : [] } }) : (d.filter.ID = function (a) { var b = a.replace(_, aa); return function (a) { var c = "undefined" != typeof a.getAttributeNode && a.getAttributeNode("id"); return c && c.value === b } }, d.find.ID = function (a, b) { if ("undefined" != typeof b.getElementById && p) { var c, d, e, f = b.getElementById(a); if (f) { if (c = f.getAttributeNode("id"), c && c.value === a) return [f]; e = b.getElementsByName(a), d = 0; while (f = e[d++]) if (c = f.getAttributeNode("id"), c && c.value === a) return [f] } return [] } }), d.find.TAG = c.getElementsByTagName ? function (a, b) { return "undefined" != typeof b.getElementsByTagName ? b.getElementsByTagName(a) : c.qsa ? b.querySelectorAll(a) : void 0 } : function (a, b) { var c, d = [], e = 0, f = b.getElementsByTagName(a); if ("*" === a) { while (c = f[e++]) 1 === c.nodeType && d.push(c); return d } return f }, d.find.CLASS = c.getElementsByClassName && function (a, b) { if ("undefined" != typeof b.getElementsByClassName && p) return b.getElementsByClassName(a) }, r = [], q = [], (c.qsa = Y.test(n.querySelectorAll)) && (ja(function (a) { o.appendChild(a).innerHTML = "<a id='" + u + "'></a><select id='" + u + "-\r\\' msallowcapture=''><option selected=''></option></select>", a.querySelectorAll("[msallowcapture^='']").length && q.push("[*^$]=" + K + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + K + "*(?:value|" + J + ")"), a.querySelectorAll("[id~=" + u + "-]").length || q.push("~="), a.querySelectorAll(":checked").length || q.push(":checked"), a.querySelectorAll("a#" + u + "+*").length || q.push(".#.+[+~]") }), ja(function (a) { a.innerHTML = "<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>"; var b = n.createElement("input"); b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + K + "*[*^$|!~]?="), 2 !== a.querySelectorAll(":enabled").length && q.push(":enabled", ":disabled"), o.appendChild(a).disabled = !0, 2 !== a.querySelectorAll(":disabled").length && q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:") })), (c.matchesSelector = Y.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ja(function (a) { c.disconnectedMatch = s.call(a, "*"), s.call(a, "[s!='']:x"), r.push("!=", N) }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = Y.test(o.compareDocumentPosition), t = b || Y.test(o.contains) ? function (a, b) { var c = 9 === a.nodeType ? a.documentElement : a, d = b && b.parentNode; return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d))) } : function (a, b) { if (b) while (b = b.parentNode) if (b === a) return !0; return !1 }, B = b ? function (a, b) { if (a === b) return l = !0, 0; var d = !a.compareDocumentPosition - !b.compareDocumentPosition; return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === n || a.ownerDocument === v && t(v, a) ? -1 : b === n || b.ownerDocument === v && t(v, b) ? 1 : k ? I(k, a) - I(k, b) : 0 : 4 & d ? -1 : 1) } : function (a, b) { if (a === b) return l = !0, 0; var c, d = 0, e = a.parentNode, f = b.parentNode, g = [a], h = [b]; if (!e || !f) return a === n ? -1 : b === n ? 1 : e ? -1 : f ? 1 : k ? I(k, a) - I(k, b) : 0; if (e === f) return la(a, b); c = a; while (c = c.parentNode) g.unshift(c); c = b; while (c = c.parentNode) h.unshift(c); while (g[d] === h[d]) d++; return d ? la(g[d], h[d]) : g[d] === v ? -1 : h[d] === v ? 1 : 0 }, n) : n }, ga.matches = function (a, b) { return ga(a, null, null, b) }, ga.matchesSelector = function (a, b) { if ((a.ownerDocument || a) !== n && m(a), b = b.replace(S, "='$1']"), c.matchesSelector && p && !A[b + " "] && (!r || !r.test(b)) && (!q || !q.test(b))) try { var d = s.call(a, b); if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d } catch (e) { } return ga(b, n, null, [a]).length > 0 }, ga.contains = function (a, b) { return (a.ownerDocument || a) !== n && m(a), t(a, b) }, ga.attr = function (a, b) { (a.ownerDocument || a) !== n && m(a); var e = d.attrHandle[b.toLowerCase()], f = e && C.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0; return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null }, ga.escape = function (a) { return (a + "").replace(ba, ca) }, ga.error = function (a) { throw new Error("Syntax error, unrecognized expression: " + a) }, ga.uniqueSort = function (a) { var b, d = [], e = 0, f = 0; if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) { while (b = a[f++]) b === a[f] && (e = d.push(f)); while (e--) a.splice(d[e], 1) } return k = null, a }, e = ga.getText = function (a) { var b, c = "", d = 0, f = a.nodeType; if (f) { if (1 === f || 9 === f || 11 === f) { if ("string" == typeof a.textContent) return a.textContent; for (a = a.firstChild; a; a = a.nextSibling) c += e(a) } else if (3 === f || 4 === f) return a.nodeValue } else while (b = a[d++]) c += e(b); return c }, d = ga.selectors = { cacheLength: 50, createPseudo: ia, match: V, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: !0 }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: !0 }, "~": { dir: "previousSibling" } }, preFilter: { ATTR: function (a) { return a[1] = a[1].replace(_, aa), a[3] = (a[3] || a[4] || a[5] || "").replace(_, aa), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4) }, CHILD: function (a) { return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || ga.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && ga.error(a[0]), a }, PSEUDO: function (a) { var b, c = !a[6] && a[2]; return V.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && T.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3)) } }, filter: { TAG: function (a) { var b = a.replace(_, aa).toLowerCase(); return "*" === a ? function () { return !0 } : function (a) { return a.nodeName && a.nodeName.toLowerCase() === b } }, CLASS: function (a) { var b = y[a + " "]; return b || (b = new RegExp("(^|" + K + ")" + a + "(" + K + "|$)")) && y(a, function (a) { return b.test("string" == typeof a.className && a.className || "undefined" != typeof a.getAttribute && a.getAttribute("class") || "") }) }, ATTR: function (a, b, c) { return function (d) { var e = ga.attr(d, a); return null == e ? "!=" === b : !b || (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e.replace(O, " ") + " ").indexOf(c) > -1 : "|=" === b && (e === c || e.slice(0, c.length + 1) === c + "-")) } }, CHILD: function (a, b, c, d, e) { var f = "nth" !== a.slice(0, 3), g = "last" !== a.slice(-4), h = "of-type" === b; return 1 === d && 0 === e ? function (a) { return !!a.parentNode } : function (b, c, i) { var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling", q = b.parentNode, r = h && b.nodeName.toLowerCase(), s = !i && !h, t = !1; if (q) { if (f) { while (p) { m = b; while (m = m[p]) if (h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) return !1; o = p = "only" === a && !o && "nextSibling" } return !0 } if (o = [g ? q.firstChild : q.lastChild], g && s) { m = q, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n && j[2], m = n && q.childNodes[n]; while (m = ++n && m && m[p] || (t = n = 0) || o.pop()) if (1 === m.nodeType && ++t && m === b) { k[a] = [w, n, t]; break } } else if (s && (m = b, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n), t === !1) while (m = ++n && m && m[p] || (t = n = 0) || o.pop()) if ((h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) && ++t && (s && (l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), k[a] = [w, t]), m === b)) break; return t -= e, t === d || t % d === 0 && t / d >= 0 } } }, PSEUDO: function (a, b) { var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || ga.error("unsupported pseudo: " + a); return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? ia(function (a, c) { var d, f = e(a, b), g = f.length; while (g--) d = I(a, f[g]), a[d] = !(c[d] = f[g]) }) : function (a) { return e(a, 0, c) }) : e } }, pseudos: { not: ia(function (a) { var b = [], c = [], d = h(a.replace(P, "$1")); return d[u] ? ia(function (a, b, c, e) { var f, g = d(a, null, e, []), h = a.length; while (h--) (f = g[h]) && (a[h] = !(b[h] = f)) }) : function (a, e, f) { return b[0] = a, d(b, null, f, c), b[0] = null, !c.pop() } }), has: ia(function (a) { return function (b) { return ga(a, b).length > 0 } }), contains: ia(function (a) { return a = a.replace(_, aa), function (b) { return (b.textContent || b.innerText || e(b)).indexOf(a) > -1 } }), lang: ia(function (a) { return U.test(a || "") || ga.error("unsupported lang: " + a), a = a.replace(_, aa).toLowerCase(), function (b) { var c; do if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType); return !1 } }), target: function (b) { var c = a.location && a.location.hash; return c && c.slice(1) === b.id }, root: function (a) { return a === o }, focus: function (a) { return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex) }, enabled: oa(!1), disabled: oa(!0), checked: function (a) { var b = a.nodeName.toLowerCase(); return "input" === b && !!a.checked || "option" === b && !!a.selected }, selected: function (a) { return a.parentNode && a.parentNode.selectedIndex, a.selected === !0 }, empty: function (a) { for (a = a.firstChild; a; a = a.nextSibling) if (a.nodeType < 6) return !1; return !0 }, parent: function (a) { return !d.pseudos.empty(a) }, header: function (a) { return X.test(a.nodeName) }, input: function (a) { return W.test(a.nodeName) }, button: function (a) { var b = a.nodeName.toLowerCase(); return "input" === b && "button" === a.type || "button" === b }, text: function (a) { var b; return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase()) }, first: pa(function () { return [0] }), last: pa(function (a, b) { return [b - 1] }), eq: pa(function (a, b, c) { return [c < 0 ? c + b : c] }), even: pa(function (a, b) { for (var c = 0; c < b; c += 2) a.push(c); return a }), odd: pa(function (a, b) { for (var c = 1; c < b; c += 2) a.push(c); return a }), lt: pa(function (a, b, c) { for (var d = c < 0 ? c + b : c; --d >= 0;) a.push(d); return a }), gt: pa(function (a, b, c) { for (var d = c < 0 ? c + b : c; ++d < b;) a.push(d); return a }) } }, d.pseudos.nth = d.pseudos.eq; for (b in { radio: !0, checkbox: !0, file: !0, password: !0, image: !0 }) d.pseudos[b] = ma(b); for (b in { submit: !0, reset: !0 }) d.pseudos[b] = na(b); function ra() { } ra.prototype = d.filters = d.pseudos, d.setFilters = new ra, g = ga.tokenize = function (a, b) { var c, e, f, g, h, i, j, k = z[a + " "]; if (k) return b ? 0 : k.slice(0); h = a, i = [], j = d.preFilter; while (h) { c && !(e = Q.exec(h)) || (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = R.exec(h)) && (c = e.shift(), f.push({ value: c, type: e[0].replace(P, " ") }), h = h.slice(c.length)); for (g in d.filter) !(e = V[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({ value: c, type: g, matches: e }), h = h.slice(c.length)); if (!c) break } return b ? h.length : h ? ga.error(a) : z(a, i).slice(0) }; function sa(a) { for (var b = 0, c = a.length, d = ""; b < c; b++) d += a[b].value; return d } function ta(a, b, c) { var d = b.dir, e = b.next, f = e || d, g = c && "parentNode" === f, h = x++; return b.first ? function (b, c, e) { while (b = b[d]) if (1 === b.nodeType || g) return a(b, c, e); return !1 } : function (b, c, i) { var j, k, l, m = [w, h]; if (i) { while (b = b[d]) if ((1 === b.nodeType || g) && a(b, c, i)) return !0 } else while (b = b[d]) if (1 === b.nodeType || g) if (l = b[u] || (b[u] = {}), k = l[b.uniqueID] || (l[b.uniqueID] = {}), e && e === b.nodeName.toLowerCase()) b = b[d] || b; else { if ((j = k[f]) && j[0] === w && j[1] === h) return m[2] = j[2]; if (k[f] = m, m[2] = a(b, c, i)) return !0 } return !1 } } function ua(a) { return a.length > 1 ? function (b, c, d) { var e = a.length; while (e--) if (!a[e](b, c, d)) return !1; return !0 } : a[0] } function va(a, b, c) { for (var d = 0, e = b.length; d < e; d++) ga(a, b[d], c); return c } function wa(a, b, c, d, e) { for (var f, g = [], h = 0, i = a.length, j = null != b; h < i; h++) (f = a[h]) && (c && !c(f, d, e) || (g.push(f), j && b.push(h))); return g } function xa(a, b, c, d, e, f) { return d && !d[u] && (d = xa(d)), e && !e[u] && (e = xa(e, f)), ia(function (f, g, h, i) { var j, k, l, m = [], n = [], o = g.length, p = f || va(b || "*", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : wa(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q; if (c && c(q, r, h, i), d) { j = wa(r, n), d(j, [], h, i), k = j.length; while (k--) (l = j[k]) && (r[n[k]] = !(q[n[k]] = l)) } if (f) { if (e || a) { if (e) { j = [], k = r.length; while (k--) (l = r[k]) && j.push(q[k] = l); e(null, r = [], j, i) } k = r.length; while (k--) (l = r[k]) && (j = e ? I(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l)) } } else r = wa(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : G.apply(g, r) }) } function ya(a) { for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = ta(function (a) { return a === b }, h, !0), l = ta(function (a) { return I(b, a) > -1 }, h, !0), m = [function (a, c, d) { var e = !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d)); return b = null, e }]; i < f; i++) if (c = d.relative[a[i].type]) m = [ta(ua(m), c)]; else { if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) { for (e = ++i; e < f; e++) if (d.relative[a[e].type]) break; return xa(i > 1 && ua(m), i > 1 && sa(a.slice(0, i - 1).concat({ value: " " === a[i - 2].type ? "*" : "" })).replace(P, "$1"), c, i < e && ya(a.slice(i, e)), e < f && ya(a = a.slice(e)), e < f && sa(a)) } m.push(c) } return ua(m) } function za(a, b) { var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) { var l, o, q, r = 0, s = "0", t = f && [], u = [], v = j, x = f || e && d.find.TAG("*", k), y = w += null == v ? 1 : Math.random() || .1, z = x.length; for (k && (j = g === n || g || k) ; s !== z && null != (l = x[s]) ; s++) { if (e && l) { o = 0, g || l.ownerDocument === n || (m(l), h = !p); while (q = a[o++]) if (q(l, g || n, h)) { i.push(l); break } k && (w = y) } c && ((l = !q && l) && r--, f && t.push(l)) } if (r += s, c && s !== r) { o = 0; while (q = b[o++]) q(t, u, g, h); if (f) { if (r > 0) while (s--) t[s] || u[s] || (u[s] = E.call(i)); u = wa(u) } G.apply(i, u), k && !f && u.length > 0 && r + b.length > 1 && ga.uniqueSort(i) } return k && (w = y, j = v), t }; return c ? ia(f) : f } return h = ga.compile = function (a, b) { var c, d = [], e = [], f = A[a + " "]; if (!f) { b || (b = g(a)), c = b.length; while (c--) f = ya(b[c]), f[u] ? d.push(f) : e.push(f); f = A(a, za(e, d)), f.selector = a } return f }, i = ga.select = function (a, b, c, e) { var f, i, j, k, l, m = "function" == typeof a && a, n = !e && g(a = m.selector || a); if (c = c || [], 1 === n.length) { if (i = n[0] = n[0].slice(0), i.length > 2 && "ID" === (j = i[0]).type && 9 === b.nodeType && p && d.relative[i[1].type]) { if (b = (d.find.ID(j.matches[0].replace(_, aa), b) || [])[0], !b) return c; m && (b = b.parentNode), a = a.slice(i.shift().value.length) } f = V.needsContext.test(a) ? 0 : i.length; while (f--) { if (j = i[f], d.relative[k = j.type]) break; if ((l = d.find[k]) && (e = l(j.matches[0].replace(_, aa), $.test(i[0].type) && qa(b.parentNode) || b))) { if (i.splice(f, 1), a = e.length && sa(i), !a) return G.apply(c, e), c; break } } } return (m || h(a, n))(e, b, !p, c, !b || $.test(a) && qa(b.parentNode) || b), c }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ja(function (a) { return 1 & a.compareDocumentPosition(n.createElement("fieldset")) }), ja(function (a) { return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href") }) || ka("type|href|height|width", function (a, b, c) { if (!c) return a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2) }), c.attributes && ja(function (a) { return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value") }) || ka("value", function (a, b, c) { if (!c && "input" === a.nodeName.toLowerCase()) return a.defaultValue }), ja(function (a) { return null == a.getAttribute("disabled") }) || ka(J, function (a, b, c) { var d; if (!c) return a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null }), ga }(a); r.find = x, r.expr = x.selectors, r.expr[":"] = r.expr.pseudos, r.uniqueSort = r.unique = x.uniqueSort, r.text = x.getText, r.isXMLDoc = x.isXML, r.contains = x.contains, r.escapeSelector = x.escape; var y = function (a, b, c) { var d = [], e = void 0 !== c; while ((a = a[b]) && 9 !== a.nodeType) if (1 === a.nodeType) { if (e && r(a).is(c)) break; d.push(a) } return d }, z = function (a, b) { for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a); return c }, A = r.expr.match.needsContext, B = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i, C = /^.[^:#\[\.,]*$/; function D(a, b, c) { return r.isFunction(b) ? r.grep(a, function (a, d) { return !!b.call(a, d, a) !== c }) : b.nodeType ? r.grep(a, function (a) { return a === b !== c }) : "string" != typeof b ? r.grep(a, function (a) { return i.call(b, a) > -1 !== c }) : C.test(b) ? r.filter(b, a, c) : (b = r.filter(b, a), r.grep(a, function (a) { return i.call(b, a) > -1 !== c && 1 === a.nodeType })) } r.filter = function (a, b, c) { var d = b[0]; return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? r.find.matchesSelector(d, a) ? [d] : [] : r.find.matches(a, r.grep(b, function (a) { return 1 === a.nodeType })) }, r.fn.extend({ find: function (a) { var b, c, d = this.length, e = this; if ("string" != typeof a) return this.pushStack(r(a).filter(function () { for (b = 0; b < d; b++) if (r.contains(e[b], this)) return !0 })); for (c = this.pushStack([]), b = 0; b < d; b++) r.find(a, e[b], c); return d > 1 ? r.uniqueSort(c) : c }, filter: function (a) { return this.pushStack(D(this, a || [], !1)) }, not: function (a) { return this.pushStack(D(this, a || [], !0)) }, is: function (a) { return !!D(this, "string" == typeof a && A.test(a) ? r(a) : a || [], !1).length } }); var E, F = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, G = r.fn.init = function (a, b, c) { var e, f; if (!a) return this; if (c = c || E, "string" == typeof a) { if (e = "<" === a[0] && ">" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : F.exec(a), !e || !e[1] && b) return !b || b.jquery ? (b || c).find(a) : this.constructor(b).find(a); if (e[1]) { if (b = b instanceof r ? b[0] : b, r.merge(this, r.parseHTML(e[1], b && b.nodeType ? b.ownerDocument || b : d, !0)), B.test(e[1]) && r.isPlainObject(b)) for (e in b) r.isFunction(this[e]) ? this[e](b[e]) : this.attr(e, b[e]); return this } return f = d.getElementById(e[2]), f && (this[0] = f, this.length = 1), this } return a.nodeType ? (this[0] = a, this.length = 1, this) : r.isFunction(a) ? void 0 !== c.ready ? c.ready(a) : a(r) : r.makeArray(a, this) }; G.prototype = r.fn, E = r(d); var H = /^(?:parents|prev(?:Until|All))/, I = { children: !0, contents: !0, next: !0, prev: !0 }; r.fn.extend({ has: function (a) { var b = r(a, this), c = b.length; return this.filter(function () { for (var a = 0; a < c; a++) if (r.contains(this, b[a])) return !0 }) }, closest: function (a, b) { var c, d = 0, e = this.length, f = [], g = "string" != typeof a && r(a); if (!A.test(a)) for (; d < e; d++) for (c = this[d]; c && c !== b; c = c.parentNode) if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && r.find.matchesSelector(c, a))) { f.push(c); break } return this.pushStack(f.length > 1 ? r.uniqueSort(f) : f) }, index: function (a) { return a ? "string" == typeof a ? i.call(r(a), this[0]) : i.call(this, a.jquery ? a[0] : a) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 }, add: function (a, b) { return this.pushStack(r.uniqueSort(r.merge(this.get(), r(a, b)))) }, addBack: function (a) { return this.add(null == a ? this.prevObject : this.prevObject.filter(a)) } }); function J(a, b) { while ((a = a[b]) && 1 !== a.nodeType); return a } r.each({ parent: function (a) { var b = a.parentNode; return b && 11 !== b.nodeType ? b : null }, parents: function (a) { return y(a, "parentNode") }, parentsUntil: function (a, b, c) { return y(a, "parentNode", c) }, next: function (a) { return J(a, "nextSibling") }, prev: function (a) { return J(a, "previousSibling") }, nextAll: function (a) { return y(a, "nextSibling") }, prevAll: function (a) { return y(a, "previousSibling") }, nextUntil: function (a, b, c) { return y(a, "nextSibling", c) }, prevUntil: function (a, b, c) { return y(a, "previousSibling", c) }, siblings: function (a) { return z((a.parentNode || {}).firstChild, a) }, children: function (a) { return z(a.firstChild) }, contents: function (a) { return a.contentDocument || r.merge([], a.childNodes) } }, function (a, b) { r.fn[a] = function (c, d) { var e = r.map(this, b, c); return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = r.filter(d, e)), this.length > 1 && (I[a] || r.uniqueSort(e), H.test(a) && e.reverse()), this.pushStack(e) } }); var K = /[^\x20\t\r\n\f]+/g; function L(a) { var b = {}; return r.each(a.match(K) || [], function (a, c) { b[c] = !0 }), b } r.Callbacks = function (a) { a = "string" == typeof a ? L(a) : r.extend({}, a); var b, c, d, e, f = [], g = [], h = -1, i = function () { for (e = a.once, d = b = !0; g.length; h = -1) { c = g.shift(); while (++h < f.length) f[h].apply(c[0], c[1]) === !1 && a.stopOnFalse && (h = f.length, c = !1) } a.memory || (c = !1), b = !1, e && (f = c ? [] : "") }, j = { add: function () { return f && (c && !b && (h = f.length - 1, g.push(c)), function d(b) { r.each(b, function (b, c) { r.isFunction(c) ? a.unique && j.has(c) || f.push(c) : c && c.length && "string" !== r.type(c) && d(c) }) }(arguments), c && !b && i()), this }, remove: function () { return r.each(arguments, function (a, b) { var c; while ((c = r.inArray(b, f, c)) > -1) f.splice(c, 1), c <= h && h-- }), this }, has: function (a) { return a ? r.inArray(a, f) > -1 : f.length > 0 }, empty: function () { return f && (f = []), this }, disable: function () { return e = g = [], f = c = "", this }, disabled: function () { return !f }, lock: function () { return e = g = [], c || b || (f = c = ""), this }, locked: function () { return !!e }, fireWith: function (a, c) { return e || (c = c || [], c = [a, c.slice ? c.slice() : c], g.push(c), b || i()), this }, fire: function () { return j.fireWith(this, arguments), this }, fired: function () { return !!d } }; return j }; function M(a) { return a } function N(a) { throw a } function O(a, b, c) { var d; try { a && r.isFunction(d = a.promise) ? d.call(a).done(b).fail(c) : a && r.isFunction(d = a.then) ? d.call(a, b, c) : b.call(void 0, a) } catch (a) { c.call(void 0, a) } } r.extend({ Deferred: function (b) { var c = [["notify", "progress", r.Callbacks("memory"), r.Callbacks("memory"), 2], ["resolve", "done", r.Callbacks("once memory"), r.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", r.Callbacks("once memory"), r.Callbacks("once memory"), 1, "rejected"]], d = "pending", e = { state: function () { return d }, always: function () { return f.done(arguments).fail(arguments), this }, "catch": function (a) { return e.then(null, a) }, pipe: function () { var a = arguments; return r.Deferred(function (b) { r.each(c, function (c, d) { var e = r.isFunction(a[d[4]]) && a[d[4]]; f[d[1]](function () { var a = e && e.apply(this, arguments); a && r.isFunction(a.promise) ? a.promise().progress(b.notify).done(b.resolve).fail(b.reject) : b[d[0] + "With"](this, e ? [a] : arguments) }) }), a = null }).promise() }, then: function (b, d, e) { var f = 0; function g(b, c, d, e) { return function () { var h = this, i = arguments, j = function () { var a, j; if (!(b < f)) { if (a = d.apply(h, i), a === c.promise()) throw new TypeError("Thenable self-resolution"); j = a && ("object" == typeof a || "function" == typeof a) && a.then, r.isFunction(j) ? e ? j.call(a, g(f, c, M, e), g(f, c, N, e)) : (f++, j.call(a, g(f, c, M, e), g(f, c, N, e), g(f, c, M, c.notifyWith))) : (d !== M && (h = void 0, i = [a]), (e || c.resolveWith)(h, i)) } }, k = e ? j : function () { try { j() } catch (a) { r.Deferred.exceptionHook && r.Deferred.exceptionHook(a, k.stackTrace), b + 1 >= f && (d !== N && (h = void 0, i = [a]), c.rejectWith(h, i)) } }; b ? k() : (r.Deferred.getStackHook && (k.stackTrace = r.Deferred.getStackHook()), a.setTimeout(k)) } } return r.Deferred(function (a) { c[0][3].add(g(0, a, r.isFunction(e) ? e : M, a.notifyWith)), c[1][3].add(g(0, a, r.isFunction(b) ? b : M)), c[2][3].add(g(0, a, r.isFunction(d) ? d : N)) }).promise() }, promise: function (a) { return null != a ? r.extend(a, e) : e } }, f = {}; return r.each(c, function (a, b) { var g = b[2], h = b[5]; e[b[1]] = g.add, h && g.add(function () { d = h }, c[3 - a][2].disable, c[0][2].lock), g.add(b[3].fire), f[b[0]] = function () { return f[b[0] + "With"](this === f ? void 0 : this, arguments), this }, f[b[0] + "With"] = g.fireWith }), e.promise(f), b && b.call(f, f), f }, when: function (a) { var b = arguments.length, c = b, d = Array(c), e = f.call(arguments), g = r.Deferred(), h = function (a) { return function (c) { d[a] = this, e[a] = arguments.length > 1 ? f.call(arguments) : c, --b || g.resolveWith(d, e) } }; if (b <= 1 && (O(a, g.done(h(c)).resolve, g.reject), "pending" === g.state() || r.isFunction(e[c] && e[c].then))) return g.then(); while (c--) O(e[c], h(c), g.reject); return g.promise() } }); var P = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; r.Deferred.exceptionHook = function (b, c) { a.console && a.console.warn && b && P.test(b.name) && a.console.warn("jQuery.Deferred exception: " + b.message, b.stack, c) }, r.readyException = function (b) { a.setTimeout(function () { throw b }) }; var Q = r.Deferred(); r.fn.ready = function (a) { return Q.then(a)["catch"](function (a) { r.readyException(a) }), this }, r.extend({ isReady: !1, readyWait: 1, holdReady: function (a) { a ? r.readyWait++ : r.ready(!0) }, ready: function (a) { (a === !0 ? --r.readyWait : r.isReady) || (r.isReady = !0, a !== !0 && --r.readyWait > 0 || Q.resolveWith(d, [r])) } }), r.ready.then = Q.then; function R() {
d.removeEventListener("DOMContentLoaded", R),
a.removeEventListener("load", R), r.ready()
} "complete" === d.readyState || "loading" !== d.readyState && !d.documentElement.doScroll ? a.setTimeout(r.ready) : (d.addEventListener("DOMContentLoaded", R), a.addEventListener("load", R)); var S = function (a, b, c, d, e, f, g) { var h = 0, i = a.length, j = null == c; if ("object" === r.type(c)) { e = !0; for (h in c) S(a, b, h, c[h], !0, f, g) } else if (void 0 !== d && (e = !0, r.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function (a, b, c) { return j.call(r(a), c) })), b)) for (; h < i; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c))); return e ? a : j ? b.call(a) : i ? b(a[0], c) : f }, T = function (a) { return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType }; function U() { this.expando = r.expando + U.uid++ } U.uid = 1, U.prototype = { cache: function (a) { var b = a[this.expando]; return b || (b = {}, T(a) && (a.nodeType ? a[this.expando] = b : Object.defineProperty(a, this.expando, { value: b, configurable: !0 }))), b }, set: function (a, b, c) { var d, e = this.cache(a); if ("string" == typeof b) e[r.camelCase(b)] = c; else for (d in b) e[r.camelCase(d)] = b[d]; return e }, get: function (a, b) { return void 0 === b ? this.cache(a) : a[this.expando] && a[this.expando][r.camelCase(b)] }, access: function (a, b, c) { return void 0 === b || b && "string" == typeof b && void 0 === c ? this.get(a, b) : (this.set(a, b, c), void 0 !== c ? c : b) }, remove: function (a, b) { var c, d = a[this.expando]; if (void 0 !== d) { if (void 0 !== b) { r.isArray(b) ? b = b.map(r.camelCase) : (b = r.camelCase(b), b = b in d ? [b] : b.match(K) || []), c = b.length; while (c--) delete d[b[c]] } (void 0 === b || r.isEmptyObject(d)) && (a.nodeType ? a[this.expando] = void 0 : delete a[this.expando]) } }, hasData: function (a) { var b = a[this.expando]; return void 0 !== b && !r.isEmptyObject(b) } }; var V = new U, W = new U, X = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, Y = /[A-Z]/g; function Z(a) { return "true" === a || "false" !== a && ("null" === a ? null : a === +a + "" ? +a : X.test(a) ? JSON.parse(a) : a) } function $(a, b, c) { var d; if (void 0 === c && 1 === a.nodeType) if (d = "data-" + b.replace(Y, "-$&").toLowerCase(), c = a.getAttribute(d), "string" == typeof c) { try { c = Z(c) } catch (e) { } W.set(a, b, c) } else c = void 0; return c } r.extend({ hasData: function (a) { return W.hasData(a) || V.hasData(a) }, data: function (a, b, c) { return W.access(a, b, c) }, removeData: function (a, b) { W.remove(a, b) }, _data: function (a, b, c) { return V.access(a, b, c) }, _removeData: function (a, b) { V.remove(a, b) } }), r.fn.extend({ data: function (a, b) { var c, d, e, f = this[0], g = f && f.attributes; if (void 0 === a) { if (this.length && (e = W.get(f), 1 === f.nodeType && !V.get(f, "hasDataAttrs"))) { c = g.length; while (c--) g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = r.camelCase(d.slice(5)), $(f, d, e[d]))); V.set(f, "hasDataAttrs", !0) } return e } return "object" == typeof a ? this.each(function () { W.set(this, a) }) : S(this, function (b) { var c; if (f && void 0 === b) { if (c = W.get(f, a), void 0 !== c) return c; if (c = $(f, a), void 0 !== c) return c } else this.each(function () { W.set(this, a, b) }) }, null, b, arguments.length > 1, null, !0) }, removeData: function (a) { return this.each(function () { W.remove(this, a) }) } }), r.extend({ queue: function (a, b, c) { var d; if (a) return b = (b || "fx") + "queue", d = V.get(a, b), c && (!d || r.isArray(c) ? d = V.access(a, b, r.makeArray(c)) : d.push(c)), d || [] }, dequeue: function (a, b) { b = b || "fx"; var c = r.queue(a, b), d = c.length, e = c.shift(), f = r._queueHooks(a, b), g = function () { r.dequeue(a, b) }; "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire() }, _queueHooks: function (a, b) { var c = b + "queueHooks"; return V.get(a, c) || V.access(a, c, { empty: r.Callbacks("once memory").add(function () { V.remove(a, [b + "queue", c]) }) }) } }), r.fn.extend({ queue: function (a, b) { var c = 2; return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? r.queue(this[0], a) : void 0 === b ? this : this.each(function () { var c = r.queue(this, a, b); r._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && r.dequeue(this, a) }) }, dequeue: function (a) { return this.each(function () { r.dequeue(this, a) }) }, clearQueue: function (a) { return this.queue(a || "fx", []) }, promise: function (a, b) { var c, d = 1, e = r.Deferred(), f = this, g = this.length, h = function () { --d || e.resolveWith(f, [f]) }; "string" != typeof a && (b = a, a = void 0), a = a || "fx"; while (g--) c = V.get(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h)); return h(), e.promise(b) } }); var _ = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, aa = new RegExp("^(?:([+-])=|)(" + _ + ")([a-z%]*)$", "i"), ba = ["Top", "Right", "Bottom", "Left"], ca = function (a, b) { return a = b || a, "none" === a.style.display || "" === a.style.display && r.contains(a.ownerDocument, a) && "none" === r.css(a, "display") }, da = function (a, b, c, d) { var e, f, g = {}; for (f in b) g[f] = a.style[f], a.style[f] = b[f]; e = c.apply(a, d || []); for (f in b) a.style[f] = g[f]; return e }; function ea(a, b, c, d) { var e, f = 1, g = 20, h = d ? function () { return d.cur() } : function () { return r.css(a, b, "") }, i = h(), j = c && c[3] || (r.cssNumber[b] ? "" : "px"), k = (r.cssNumber[b] || "px" !== j && +i) && aa.exec(r.css(a, b)); if (k && k[3] !== j) { j = j || k[3], c = c || [], k = +i || 1; do f = f || ".5", k /= f, r.style(a, b, k + j); while (f !== (f = h() / i) && 1 !== f && --g) } return c && (k = +k || +i || 0, e = c[1] ? k + (c[1] + 1) * c[2] : +c[2], d && (d.unit = j, d.start = k, d.end = e)), e } var fa = {}; function ga(a) { var b, c = a.ownerDocument, d = a.nodeName, e = fa[d]; return e ? e : (b = c.body.appendChild(c.createElement(d)), e = r.css(b, "display"), b.parentNode.removeChild(b), "none" === e && (e = "block"), fa[d] = e, e) } function ha(a, b) { for (var c, d, e = [], f = 0, g = a.length; f < g; f++) d = a[f], d.style && (c = d.style.display, b ? ("none" === c && (e[f] = V.get(d, "display") || null, e[f] || (d.style.display = "")), "" === d.style.display && ca(d) && (e[f] = ga(d))) : "none" !== c && (e[f] = "none", V.set(d, "display", c))); for (f = 0; f < g; f++) null != e[f] && (a[f].style.display = e[f]); return a } r.fn.extend({ show: function () { return ha(this, !0) }, hide: function () { return ha(this) }, toggle: function (a) { return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function () { ca(this) ? r(this).show() : r(this).hide() }) } }); var ia = /^(?:checkbox|radio)$/i, ja = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i, ka = /^$|\/(?:java|ecma)script/i, la = { 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, "", ""] }; la.optgroup = la.option, la.tbody = la.tfoot = la.colgroup = la.caption = la.thead, la.th = la.td; function ma(a, b) { var c; return c = "undefined" != typeof a.getElementsByTagName ? a.getElementsByTagName(b || "*") : "undefined" != typeof a.querySelectorAll ? a.querySelectorAll(b || "*") : [], void 0 === b || b && r.nodeName(a, b) ? r.merge([a], c) : c } function na(a, b) { for (var c = 0, d = a.length; c < d; c++) V.set(a[c], "globalEval", !b || V.get(b[c], "globalEval")) } var oa = /<|&#?\w+;/; function pa(a, b, c, d, e) { for (var f, g, h, i, j, k, l = b.createDocumentFragment(), m = [], n = 0, o = a.length; n < o; n++) if (f = a[n], f || 0 === f) if ("object" === r.type(f)) r.merge(m, f.nodeType ? [f] : f); else if (oa.test(f)) { g = g || l.appendChild(b.createElement("div")), h = (ja.exec(f) || ["", ""])[1].toLowerCase(), i = la[h] || la._default, g.innerHTML = i[1] + r.htmlPrefilter(f) + i[2], k = i[0]; while (k--) g = g.lastChild; r.merge(m, g.childNodes), g = l.firstChild, g.textContent = "" } else m.push(b.createTextNode(f)); l.textContent = "", n = 0; while (f = m[n++]) if (d && r.inArray(f, d) > -1) e && e.push(f); else if (j = r.contains(f.ownerDocument, f), g = ma(l.appendChild(f), "script"), j && na(g), c) { k = 0; while (f = g[k++]) ka.test(f.type || "") && c.push(f) } return l } !function () { var a = d.createDocumentFragment(), b = a.appendChild(d.createElement("div")), c = d.createElement("input"); c.setAttribute("type", "radio"), c.setAttribute("checked", "checked"), c.setAttribute("name", "t"), b.appendChild(c), o.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = "<textarea>x</textarea>", o.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue }(); var qa = d.documentElement, ra = /^key/, sa = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, ta = /^([^.]*)(?:\.(.+)|)/; function ua() { return !0 } function va() { return !1 } function wa() { try { return d.activeElement } catch (a) { } } function xa(a, b, c, d, e, f) { var g, h; if ("object" == typeof b) { "string" != typeof c && (d = d || c, c = void 0); for (h in b) xa(a, h, c, d, b[h], f); return a } if (null == d && null == e ? (e = c, d = c = void 0) : null == e && ("string" == typeof c ? (e = d, d = void 0) : (e = d, d = c, c = void 0)), e === !1) e = va; else if (!e) return a; return 1 === f && (g = e, e = function (a) { return r().off(a), g.apply(this, arguments) }, e.guid = g.guid || (g.guid = r.guid++)), a.each(function () { r.event.add(this, b, e, d, c) }) } r.event = { global: {}, add: function (a, b, c, d, e) { var f, g, h, i, j, k, l, m, n, o, p, q = V.get(a); if (q) { c.handler && (f = c, c = f.handler, e = f.selector), e && r.find.matchesSelector(qa, e), c.guid || (c.guid = r.guid++), (i = q.events) || (i = q.events = {}), (g = q.handle) || (g = q.handle = function (b) { return "undefined" != typeof r && r.event.triggered !== b.type ? r.event.dispatch.apply(a, arguments) : void 0 }), b = (b || "").match(K) || [""], j = b.length; while (j--) h = ta.exec(b[j]) || [], n = p = h[1], o = (h[2] || "").split(".").sort(), n && (l = r.event.special[n] || {}, n = (e ? l.delegateType : l.bindType) || n, l = r.event.special[n] || {}, k = r.extend({ type: n, origType: p, data: d, handler: c, guid: c.guid, selector: e, needsContext: e && r.expr.match.needsContext.test(e), namespace: o.join(".") }, f), (m = i[n]) || (m = i[n] = [], m.delegateCount = 0, l.setup && l.setup.call(a, d, o, g) !== !1 || a.addEventListener && a.addEventListener(n, g)), l.add && (l.add.call(a, k), k.handler.guid || (k.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, k) : m.push(k), r.event.global[n] = !0) } }, remove: function (a, b, c, d, e) { var f, g, h, i, j, k, l, m, n, o, p, q = V.hasData(a) && V.get(a); if (q && (i = q.events)) { b = (b || "").match(K) || [""], j = b.length; while (j--) if (h = ta.exec(b[j]) || [], n = p = h[1], o = (h[2] || "").split(".").sort(), n) { l = r.event.special[n] || {}, n = (d ? l.delegateType : l.bindType) || n, m = i[n] || [], h = h[2] && new RegExp("(^|\\.)" + o.join("\\.(?:.*\\.|)") + "(\\.|$)"), g = f = m.length; while (f--) k = m[f], !e && p !== k.origType || c && c.guid !== k.guid || h && !h.test(k.namespace) || d && d !== k.selector && ("**" !== d || !k.selector) || (m.splice(f, 1), k.selector && m.delegateCount--, l.remove && l.remove.call(a, k)); g && !m.length && (l.teardown && l.teardown.call(a, o, q.handle) !== !1 || r.removeEvent(a, n, q.handle), delete i[n]) } else for (n in i) r.event.remove(a, n + b[j], c, d, !0); r.isEmptyObject(i) && V.remove(a, "handle events") } }, dispatch: function (a) { var b = r.event.fix(a), c, d, e, f, g, h, i = new Array(arguments.length), j = (V.get(this, "events") || {})[b.type] || [], k = r.event.special[b.type] || {}; for (i[0] = b, c = 1; c < arguments.length; c++) i[c] = arguments[c]; if (b.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, b) !== !1) { h = r.event.handlers.call(this, b, j), c = 0; while ((f = h[c++]) && !b.isPropagationStopped()) { b.currentTarget = f.elem, d = 0; while ((g = f.handlers[d++]) && !b.isImmediatePropagationStopped()) b.rnamespace && !b.rnamespace.test(g.namespace) || (b.handleObj = g, b.data = g.data, e = ((r.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== e && (b.result = e) === !1 && (b.preventDefault(), b.stopPropagation())) } return k.postDispatch && k.postDispatch.call(this, b), b.result } }, handlers: function (a, b) { var c, d, e, f, g, h = [], i = b.delegateCount, j = a.target; if (i && j.nodeType && !("click" === a.type && a.button >= 1)) for (; j !== this; j = j.parentNode || this) if (1 === j.nodeType && ("click" !== a.type || j.disabled !== !0)) { for (f = [], g = {}, c = 0; c < i; c++) d = b[c], e = d.selector + " ", void 0 === g[e] && (g[e] = d.needsContext ? r(e, this).index(j) > -1 : r.find(e, this, null, [j]).length), g[e] && f.push(d); f.length && h.push({ elem: j, handlers: f }) } return j = this, i < b.length && h.push({ elem: j, handlers: b.slice(i) }), h }, addProp: function (a, b) { Object.defineProperty(r.Event.prototype, a, { enumerable: !0, configurable: !0, get: r.isFunction(b) ? function () { if (this.originalEvent) return b(this.originalEvent) } : function () { if (this.originalEvent) return this.originalEvent[a] }, set: function (b) { Object.defineProperty(this, a, { enumerable: !0, configurable: !0, writable: !0, value: b }) } }) }, fix: function (a) { return a[r.expando] ? a : new r.Event(a) }, special: { load: { noBubble: !0 }, focus: { trigger: function () { if (this !== wa() && this.focus) return this.focus(), !1 }, delegateType: "focusin" }, blur: { trigger: function () { if (this === wa() && this.blur) return this.blur(), !1 }, delegateType: "focusout" }, click: { trigger: function () { if ("checkbox" === this.type && this.click && r.nodeName(this, "input")) return this.click(), !1 }, _default: function (a) { return r.nodeName(a.target, "a") } }, beforeunload: { postDispatch: function (a) { void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result) } } } }, r.removeEvent = function (a, b, c) { a.removeEventListener && a.removeEventListener(b, c) }, r.Event = function (a, b) { return this instanceof r.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? ua : va, this.target = a.target && 3 === a.target.nodeType ? a.target.parentNode : a.target, this.currentTarget = a.currentTarget, this.relatedTarget = a.relatedTarget) : this.type = a, b && r.extend(this, b), this.timeStamp = a && a.timeStamp || r.now(), void (this[r.expando] = !0)) : new r.Event(a, b) }, r.Event.prototype = { constructor: r.Event, isDefaultPrevented: va, isPropagationStopped: va, isImmediatePropagationStopped: va, isSimulated: !1, preventDefault: function () { var a = this.originalEvent; this.isDefaultPrevented = ua, a && !this.isSimulated && a.preventDefault() }, stopPropagation: function () { var a = this.originalEvent; this.isPropagationStopped = ua, a && !this.isSimulated && a.stopPropagation() }, stopImmediatePropagation: function () { var a = this.originalEvent; this.isImmediatePropagationStopped = ua, a && !this.isSimulated && a.stopImmediatePropagation(), this.stopPropagation() } }, r.each({ altKey: !0, bubbles: !0, cancelable: !0, changedTouches: !0, ctrlKey: !0, detail: !0, eventPhase: !0, metaKey: !0, pageX: !0, pageY: !0, shiftKey: !0, view: !0, "char": !0, charCode: !0, key: !0, keyCode: !0, button: !0, buttons: !0, clientX: !0, clientY: !0, offsetX: !0, offsetY: !0, pointerId: !0, pointerType: !0, screenX: !0, screenY: !0, targetTouches: !0, toElement: !0, touches: !0, which: function (a) { var b = a.button; return null == a.which && ra.test(a.type) ? null != a.charCode ? a.charCode : a.keyCode : !a.which && void 0 !== b && sa.test(a.type) ? 1 & b ? 1 : 2 & b ? 3 : 4 & b ? 2 : 0 : a.which } }, r.event.addProp), r.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function (a, b) { r.event.special[a] = { delegateType: b, bindType: b, handle: function (a) { var c, d = this, e = a.relatedTarget, f = a.handleObj; return e && (e === d || r.contains(d, e)) || (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c } } }), r.fn.extend({ on: function (a, b, c, d) { return xa(this, a, b, c, d) }, one: function (a, b, c, d) { return xa(this, a, b, c, d, 1) }, off: function (a, b, c) { var d, e; if (a && a.preventDefault && a.handleObj) return d = a.handleObj, r(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this; if ("object" == typeof a) { for (e in a) this.off(e, b, a[e]); return this } return b !== !1 && "function" != typeof b || (c = b, b = void 0), c === !1 && (c = va), this.each(function () { r.event.remove(this, a, c, b) }) } }); var ya = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, za = /<script|<style|<link/i, Aa = /checked\s*(?:[^=]|=\s*.checked.)/i, Ba = /^true\/(.*)/, Ca = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; function Da(a, b) { return r.nodeName(a, "table") && r.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a : a } function Ea(a) { return a.type = (null !== a.getAttribute("type")) + "/" + a.type, a } function Fa(a) { var b = Ba.exec(a.type); return b ? a.type = b[1] : a.removeAttribute("type"), a } function Ga(a, b) { var c, d, e, f, g, h, i, j; if (1 === b.nodeType) { if (V.hasData(a) && (f = V.access(a), g = V.set(b, f), j = f.events)) { delete g.handle, g.events = {}; for (e in j) for (c = 0, d = j[e].length; c < d; c++) r.event.add(b, e, j[e][c]) } W.hasData(a) && (h = W.access(a), i = r.extend({}, h), W.set(b, i)) } } function Ha(a, b) { var c = b.nodeName.toLowerCase(); "input" === c && ia.test(a.type) ? b.checked = a.checked : "input" !== c && "textarea" !== c || (b.defaultValue = a.defaultValue) } function Ia(a, b, c, d) { b = g.apply([], b); var e, f, h, i, j, k, l = 0, m = a.length, n = m - 1, q = b[0], s = r.isFunction(q); if (s || m > 1 && "string" == typeof q && !o.checkClone && Aa.test(q)) return a.each(function (e) { var f = a.eq(e); s && (b[0] = q.call(this, e, f.html())), Ia(f, b, c, d) }); if (m && (e = pa(b, a[0].ownerDocument, !1, a, d), f = e.firstChild, 1 === e.childNodes.length && (e = f), f || d)) { for (h = r.map(ma(e, "script"), Ea), i = h.length; l < m; l++) j = e, l !== n && (j = r.clone(j, !0, !0), i && r.merge(h, ma(j, "script"))), c.call(a[l], j, l); if (i) for (k = h[h.length - 1].ownerDocument, r.map(h, Fa), l = 0; l < i; l++) j = h[l], ka.test(j.type || "") && !V.access(j, "globalEval") && r.contains(k, j) && (j.src ? r._evalUrl && r._evalUrl(j.src) : p(j.textContent.replace(Ca, ""), k)) } return a } function Ja(a, b, c) { for (var d, e = b ? r.filter(b, a) : a, f = 0; null != (d = e[f]) ; f++) c || 1 !== d.nodeType || r.cleanData(ma(d)), d.parentNode && (c && r.contains(d.ownerDocument, d) && na(ma(d, "script")), d.parentNode.removeChild(d)); return a } r.extend({ htmlPrefilter: function (a) { return a.replace(ya, "<$1></$2>") }, clone: function (a, b, c) { var d, e, f, g, h = a.cloneNode(!0), i = r.contains(a.ownerDocument, a); if (!(o.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || r.isXMLDoc(a))) for (g = ma(h), f = ma(a), d = 0, e = f.length; d < e; d++) Ha(f[d], g[d]); if (b) if (c) for (f = f || ma(a), g = g || ma(h), d = 0, e = f.length; d < e; d++) Ga(f[d], g[d]); else Ga(a, h); return g = ma(h, "script"), g.length > 0 && na(g, !i && ma(a, "script")), h }, cleanData: function (a) { for (var b, c, d, e = r.event.special, f = 0; void 0 !== (c = a[f]) ; f++) if (T(c)) { if (b = c[V.expando]) { if (b.events) for (d in b.events) e[d] ? r.event.remove(c, d) : r.removeEvent(c, d, b.handle); c[V.expando] = void 0 } c[W.expando] && (c[W.expando] = void 0) } } }), r.fn.extend({ detach: function (a) { return Ja(this, a, !0) }, remove: function (a) { return Ja(this, a) }, text: function (a) { return S(this, function (a) { return void 0 === a ? r.text(this) : this.empty().each(function () { 1 !== this.nodeType && 11 !== this.nodeType && 9 !== this.nodeType || (this.textContent = a) }) }, null, a, arguments.length) }, append: function () { return Ia(this, arguments, function (a) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var b = Da(this, a); b.appendChild(a) } }) }, prepend: function () { return Ia(this, arguments, function (a) { if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { var b = Da(this, a); b.insertBefore(a, b.firstChild) } }) }, before: function () { return Ia(this, arguments, function (a) { this.parentNode && this.parentNode.insertBefore(a, this) }) }, after: function () { return Ia(this, arguments, function (a) { this.parentNode && this.parentNode.insertBefore(a, this.nextSibling) }) }, empty: function () { for (var a, b = 0; null != (a = this[b]) ; b++) 1 === a.nodeType && (r.cleanData(ma(a, !1)), a.textContent = ""); return this }, clone: function (a, b) { return a = null != a && a, b = null == b ? a : b, this.map(function () { return r.clone(this, a, b) }) }, html: function (a) { return S(this, function (a) { var b = this[0] || {}, c = 0, d = this.length; if (void 0 === a && 1 === b.nodeType) return b.innerHTML; if ("string" == typeof a && !za.test(a) && !la[(ja.exec(a) || ["", ""])[1].toLowerCase()]) { a = r.htmlPrefilter(a); try { for (; c < d; c++) b = this[c] || {}, 1 === b.nodeType && (r.cleanData(ma(b, !1)), b.innerHTML = a); b = 0 } catch (e) { } } b && this.empty().append(a) }, null, a, arguments.length) }, replaceWith: function () { var a = []; return Ia(this, arguments, function (b) { var c = this.parentNode; r.inArray(this, a) < 0 && (r.cleanData(ma(this)), c && c.replaceChild(b, this)) }, a) } }), r.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function (a, b) { r.fn[a] = function (a) { for (var c, d = [], e = r(a), f = e.length - 1, g = 0; g <= f; g++) c = g === f ? this : this.clone(!0), r(e[g])[b](c), h.apply(d, c.get()); return this.pushStack(d) } }); var Ka = /^margin/, La = new RegExp("^(" + _ + ")(?!px)[a-z%]+$", "i"), Ma = function (b) { var c = b.ownerDocument.defaultView; return c && c.opener || (c = a), c.getComputedStyle(b) }; !function () { function b() { if (i) { i.style.cssText = "box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%", i.innerHTML = "", qa.appendChild(h); var b = a.getComputedStyle(i); c = "1%" !== b.top, g = "2px" === b.marginLeft, e = "4px" === b.width, i.style.marginRight = "50%", f = "4px" === b.marginRight, qa.removeChild(h), i = null } } var c, e, f, g, h = d.createElement("div"), i = d.createElement("div"); i.style && (i.style.backgroundClip = "content-box", i.cloneNode(!0).style.backgroundClip = "", o.clearCloneStyle = "content-box" === i.style.backgroundClip, h.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute", h.appendChild(i), r.extend(o, { pixelPosition: function () { return b(), c }, boxSizingReliable: function () { return b(), e }, pixelMarginRight: function () { return b(), f }, reliableMarginLeft: function () { return b(), g } })) }(); function Na(a, b, c) { var d, e, f, g, h = a.style; return c = c || Ma(a), c && (g = c.getPropertyValue(b) || c[b], "" !== g || r.contains(a.ownerDocument, a) || (g = r.style(a, b)), !o.pixelMarginRight() && La.test(g) && Ka.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 !== g ? g + "" : g } function Oa(a, b) { return { get: function () { return a() ? void delete this.get : (this.get = b).apply(this, arguments) } } } var Pa = /^(none|table(?!-c[ea]).+)/, Qa = { position: "absolute", visibility: "hidden", display: "block" }, Ra = { letterSpacing: "0", fontWeight: "400" }, Sa = ["Webkit", "Moz", "ms"], Ta = d.createElement("div").style; function Ua(a) { if (a in Ta) return a; var b = a[0].toUpperCase() + a.slice(1), c = Sa.length; while (c--) if (a = Sa[c] + b, a in Ta) return a } function Va(a, b, c) { var d = aa.exec(b); return d ? Math.max(0, d[2] - (c || 0)) + (d[3] || "px") : b } function Wa(a, b, c, d, e) { var f, g = 0; for (f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0; f < 4; f += 2) "margin" === c && (g += r.css(a, c + ba[f], !0, e)), d ? ("content" === c && (g -= r.css(a, "padding" + ba[f], !0, e)), "margin" !== c && (g -= r.css(a, "border" + ba[f] + "Width", !0, e))) : (g += r.css(a, "padding" + ba[f], !0, e), "padding" !== c && (g += r.css(a, "border" + ba[f] + "Width", !0, e))); return g } function Xa(a, b, c) { var d, e = !0, f = Ma(a), g = "border-box" === r.css(a, "boxSizing", !1, f); if (a.getClientRects().length && (d = a.getBoundingClientRect()[b]), d <= 0 || null == d) { if (d = Na(a, b, f), (d < 0 || null == d) && (d = a.style[b]), La.test(d)) return d; e = g && (o.boxSizingReliable() || d === a.style[b]), d = parseFloat(d) || 0 } return d + Wa(a, b, c || (g ? "border" : "content"), e, f) + "px" } r.extend({ cssHooks: { opacity: { get: function (a, b) { if (b) { var c = Na(a, "opacity"); return "" === c ? "1" : c } } } }, cssNumber: { animationIterationCount: !0, 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 (a, b, c, d) { if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) { var e, f, g, h = r.camelCase(b), i = a.style; return b = r.cssProps[h] || (r.cssProps[h] = Ua(h) || h), g = r.cssHooks[b] || r.cssHooks[h], void 0 === c ? g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b] : (f = typeof c, "string" === f && (e = aa.exec(c)) && e[1] && (c = ea(a, b, e), f = "number"), null != c && c === c && ("number" === f && (c += e && e[3] || (r.cssNumber[h] ? "" : "px")), o.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), g && "set" in g && void 0 === (c = g.set(a, c, d)) || (i[b] = c)), void 0) } }, css: function (a, b, c, d) { var e, f, g, h = r.camelCase(b); return b = r.cssProps[h] || (r.cssProps[h] = Ua(h) || h), g = r.cssHooks[b] || r.cssHooks[h], g && "get" in g && (e = g.get(a, !0, c)), void 0 === e && (e = Na(a, b, d)), "normal" === e && b in Ra && (e = Ra[b]), "" === c || c ? (f = parseFloat(e), c === !0 || isFinite(f) ? f || 0 : e) : e } }), r.each(["height", "width"], function (a, b) { r.cssHooks[b] = { get: function (a, c, d) { if (c) return !Pa.test(r.css(a, "display")) || a.getClientRects().length && a.getBoundingClientRect().width ? Xa(a, b, d) : da(a, Qa, function () { return Xa(a, b, d) }) }, set: function (a, c, d) { var e, f = d && Ma(a), g = d && Wa(a, b, d, "border-box" === r.css(a, "boxSizing", !1, f), f); return g && (e = aa.exec(c)) && "px" !== (e[3] || "px") && (a.style[b] = c, c = r.css(a, b)), Va(a, c, g) } } }), r.cssHooks.marginLeft = Oa(o.reliableMarginLeft, function (a, b) { if (b) return (parseFloat(Na(a, "marginLeft")) || a.getBoundingClientRect().left - da(a, { marginLeft: 0 }, function () { return a.getBoundingClientRect().left })) + "px" }), r.each({ margin: "", padding: "", border: "Width" }, function (a, b) { r.cssHooks[a + b] = { expand: function (c) { for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; d < 4; d++) e[a + ba[d] + b] = f[d] || f[d - 2] || f[0]; return e } }, Ka.test(a) || (r.cssHooks[a + b].set = Va) }), r.fn.extend({ css: function (a, b) { return S(this, function (a, b, c) { var d, e, f = {}, g = 0; if (r.isArray(b)) { for (d = Ma(a), e = b.length; g < e; g++) f[b[g]] = r.css(a, b[g], !1, d); return f } return void 0 !== c ? r.style(a, b, c) : r.css(a, b) }, a, b, arguments.length > 1) } }); function Ya(a, b, c, d, e) { return new Ya.prototype.init(a, b, c, d, e) } r.Tween = Ya, Ya.prototype = { constructor: Ya, init: function (a, b, c, d, e, f) { this.elem = a, this.prop = c, this.easing = e || r.easing._default, this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (r.cssNumber[c] ? "" : "px") }, cur: function () { var a = Ya.propHooks[this.prop]; return a && a.get ? a.get(this) : Ya.propHooks._default.get(this) }, run: function (a) { var b, c = Ya.propHooks[this.prop]; return this.options.duration ? this.pos = b = r.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : this.pos = b = a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : Ya.propHooks._default.set(this), this } }, Ya.prototype.init.prototype = Ya.prototype, Ya.propHooks = { _default: { get: function (a) { var b; return 1 !== a.elem.nodeType || null != a.elem[a.prop] && null == a.elem.style[a.prop] ? a.elem[a.prop] : (b = r.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) }, set: function (a) { r.fx.step[a.prop] ? r.fx.step[a.prop](a) : 1 !== a.elem.nodeType || null == a.elem.style[r.cssProps[a.prop]] && !r.cssHooks[a.prop] ? a.elem[a.prop] = a.now : r.style(a.elem, a.prop, a.now + a.unit) } } }, Ya.propHooks.scrollTop = Ya.propHooks.scrollLeft = { set: function (a) { a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now) } }, r.easing = { linear: function (a) { return a }, swing: function (a) { return .5 - Math.cos(a * Math.PI) / 2 }, _default: "swing" }, r.fx = Ya.prototype.init, r.fx.step = {}; var Za, $a, _a = /^(?:toggle|show|hide)$/, ab = /queueHooks$/; function bb() { $a && (a.requestAnimationFrame(bb), r.fx.tick()) } function cb() { return a.setTimeout(function () { Za = void 0 }), Za = r.now() } function db(a, b) { var c, d = 0, e = { height: a }; for (b = b ? 1 : 0; d < 4; d += 2 - b) c = ba[d], e["margin" + c] = e["padding" + c] = a; return b && (e.opacity = e.width = a), e } function eb(a, b, c) { for (var d, e = (hb.tweeners[b] || []).concat(hb.tweeners["*"]), f = 0, g = e.length; f < g; f++) if (d = e[f].call(c, b, a)) return d } function fb(a, b, c) { var d, e, f, g, h, i, j, k, l = "width" in b || "height" in b, m = this, n = {}, o = a.style, p = a.nodeType && ca(a), q = V.get(a, "fxshow"); c.queue || (g = r._queueHooks(a, "fx"), null == g.unqueued && (g.unqueued = 0, h = g.empty.fire, g.empty.fire = function () { g.unqueued || h() }), g.unqueued++, m.always(function () { m.always(function () { g.unqueued--, r.queue(a, "fx").length || g.empty.fire() }) })); for (d in b) if (e = b[d], _a.test(e)) { if (delete b[d], f = f || "toggle" === e, e === (p ? "hide" : "show")) { if ("show" !== e || !q || void 0 === q[d]) continue; p = !0 } n[d] = q && q[d] || r.style(a, d) } if (i = !r.isEmptyObject(b), i || !r.isEmptyObject(n)) { l && 1 === a.nodeType && (c.overflow = [o.overflow, o.overflowX, o.overflowY], j = q && q.display, null == j && (j = V.get(a, "display")), k = r.css(a, "display"), "none" === k && (j ? k = j : (ha([a], !0), j = a.style.display || j, k = r.css(a, "display"), ha([a]))), ("inline" === k || "inline-block" === k && null != j) && "none" === r.css(a, "float") && (i || (m.done(function () { o.display = j }), null == j && (k = o.display, j = "none" === k ? "" : k)), o.display = "inline-block")), c.overflow && (o.overflow = "hidden", m.always(function () { o.overflow = c.overflow[0], o.overflowX = c.overflow[1], o.overflowY = c.overflow[2] })), i = !1; for (d in n) i || (q ? "hidden" in q && (p = q.hidden) : q = V.access(a, "fxshow", { display: j }), f && (q.hidden = !p), p && ha([a], !0), m.done(function () { p || ha([a]), V.remove(a, "fxshow"); for (d in n) r.style(a, d, n[d]) })), i = eb(p ? q[d] : 0, d, m), d in q || (q[d] = i.start, p && (i.end = i.start, i.start = 0)) } } function gb(a, b) { var c, d, e, f, g; for (c in a) if (d = r.camelCase(c), e = b[d], f = a[c], r.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = r.cssHooks[d], g && "expand" in g) { f = g.expand(f), delete a[d]; for (c in f) c in a || (a[c] = f[c], b[c] = e) } else b[d] = e } function hb(a, b, c) { var d, e, f = 0, g = hb.prefilters.length, h = r.Deferred().always(function () { delete i.elem }), i = function () { if (e) return !1; for (var b = Za || cb(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; g < i; g++) j.tweens[g].run(f); return h.notifyWith(a, [j, f, c]), f < 1 && i ? c : (h.resolveWith(a, [j]), !1) }, j = h.promise({ elem: a, props: r.extend({}, b), opts: r.extend(!0, { specialEasing: {}, easing: r.easing._default }, c), originalProperties: b, originalOptions: c, startTime: Za || cb(), duration: c.duration, tweens: [], createTween: function (b, c) { var d = r.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing); return j.tweens.push(d), d }, stop: function (b) { var c = 0, d = b ? j.tweens.length : 0; if (e) return this; for (e = !0; c < d; c++) j.tweens[c].run(1); return b ? (h.notifyWith(a, [j, 1, 0]), h.resolveWith(a, [j, b])) : h.rejectWith(a, [j, b]), this } }), k = j.props; for (gb(k, j.opts.specialEasing) ; f < g; f++) if (d = hb.prefilters[f].call(j, a, k, j.opts)) return r.isFunction(d.stop) && (r._queueHooks(j.elem, j.opts.queue).stop = r.proxy(d.stop, d)), d; return r.map(k, eb, j), r.isFunction(j.opts.start) && j.opts.start.call(a, j), r.fx.timer(r.extend(i, { elem: a, anim: j, queue: j.opts.queue })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always) } r.Animation = r.extend(hb, { tweeners: { "*": [function (a, b) { var c = this.createTween(a, b); return ea(c.elem, a, aa.exec(b), c), c }] }, tweener: function (a, b) { r.isFunction(a) ? (b = a, a = ["*"]) : a = a.match(K); for (var c, d = 0, e = a.length; d < e; d++) c = a[d], hb.tweeners[c] = hb.tweeners[c] || [], hb.tweeners[c].unshift(b) }, prefilters: [fb], prefilter: function (a, b) { b ? hb.prefilters.unshift(a) : hb.prefilters.push(a) } }), r.speed = function (a, b, c) { var e = a && "object" == typeof a ? r.extend({}, a) : { complete: c || !c && b || r.isFunction(a) && a, duration: a, easing: c && b || b && !r.isFunction(b) && b }; return r.fx.off || d.hidden ? e.duration = 0 : "number" != typeof e.duration && (e.duration in r.fx.speeds ? e.duration = r.fx.speeds[e.duration] : e.duration = r.fx.speeds._default), null != e.queue && e.queue !== !0 || (e.queue = "fx"), e.old = e.complete, e.complete = function () { r.isFunction(e.old) && e.old.call(this), e.queue && r.dequeue(this, e.queue) }, e }, r.fn.extend({ fadeTo: function (a, b, c, d) { return this.filter(ca).css("opacity", 0).show().end().animate({ opacity: b }, a, c, d) }, animate: function (a, b, c, d) { var e = r.isEmptyObject(a), f = r.speed(b, c, d), g = function () { var b = hb(this, r.extend({}, a), f); (e || V.get(this, "finish")) && b.stop(!0) }; return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g) }, stop: function (a, b, c) { var d = function (a) { var b = a.stop; delete a.stop, b(c) }; return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function () { var b = !0, e = null != a && a + "queueHooks", f = r.timers, g = V.get(this); if (e) g[e] && g[e].stop && d(g[e]); else for (e in g) g[e] && g[e].stop && ab.test(e) && d(g[e]); for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1)); !b && c || r.dequeue(this, a) }) }, finish: function (a) { return a !== !1 && (a = a || "fx"), this.each(function () { var b, c = V.get(this), d = c[a + "queue"], e = c[a + "queueHooks"], f = r.timers, g = d ? d.length : 0; for (c.finish = !0, r.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1)); for (b = 0; b < g; b++) d[b] && d[b].finish && d[b].finish.call(this); delete c.finish }) } }), r.each(["toggle", "show", "hide"], function (a, b) { var c = r.fn[b]; r.fn[b] = function (a, d, e) { return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(db(b, !0), a, d, e) } }), r.each({ slideDown: db("show"), slideUp: db("hide"), slideToggle: db("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function (a, b) { r.fn[a] = function (a, c, d) { return this.animate(b, a, c, d) } }), r.timers = [], r.fx.tick = function () { var a, b = 0, c = r.timers; for (Za = r.now() ; b < c.length; b++) a = c[b], a() || c[b] !== a || c.splice(b--, 1); c.length || r.fx.stop(), Za = void 0 }, r.fx.timer = function (a) { r.timers.push(a), a() ? r.fx.start() : r.timers.pop() }, r.fx.interval = 13, r.fx.start = function () { $a || ($a = a.requestAnimationFrame ? a.requestAnimationFrame(bb) : a.setInterval(r.fx.tick, r.fx.interval)) }, r.fx.stop = function () { a.cancelAnimationFrame ? a.cancelAnimationFrame($a) : a.clearInterval($a), $a = null }, r.fx.speeds = { slow: 600, fast: 200, _default: 400 }, r.fn.delay = function (b, c) { return b = r.fx ? r.fx.speeds[b] || b : b, c = c || "fx", this.queue(c, function (c, d) { var e = a.setTimeout(c, b); d.stop = function () { a.clearTimeout(e) } }) }, function () { var a = d.createElement("input"), b = d.createElement("select"), c = b.appendChild(d.createElement("option")); a.type = "checkbox", o.checkOn = "" !== a.value, o.optSelected = c.selected, a = d.createElement("input"), a.value = "t", a.type = "radio", o.radioValue = "t" === a.value }(); var ib, jb = r.expr.attrHandle; r.fn.extend({ attr: function (a, b) { return S(this, r.attr, a, b, arguments.length > 1) }, removeAttr: function (a) { return this.each(function () { r.removeAttr(this, a) }) } }), r.extend({
attr: function (a, b, c) {
var d, e, f = a.nodeType; if (3 !== f && 8 !== f && 2 !== f) return "undefined" == typeof a.getAttribute ? r.prop(a, b, c) : (1 === f && r.isXMLDoc(a) || (e = r.attrHooks[b.toLowerCase()] || (r.expr.match.bool.test(b) ? ib : void 0)),
void 0 !== c ? null === c ? void r.removeAttr(a, b) : e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : (a.setAttribute(b, c + ""), c) : e && "get" in e && null !== (d = e.get(a, b)) ? d : (d = r.find.attr(a, b), null == d ? void 0 : d))
}, attrHooks: { type: { set: function (a, b) { if (!o.radioValue && "radio" === b && r.nodeName(a, "input")) { var c = a.value; return a.setAttribute("type", b), c && (a.value = c), b } } } }, removeAttr: function (a, b) { var c, d = 0, e = b && b.match(K); if (e && 1 === a.nodeType) while (c = e[d++]) a.removeAttribute(c) }
}), ib = { set: function (a, b, c) { return b === !1 ? r.removeAttr(a, c) : a.setAttribute(c, c), c } }, r.each(r.expr.match.bool.source.match(/\w+/g), function (a, b) { var c = jb[b] || r.find.attr; jb[b] = function (a, b, d) { var e, f, g = b.toLowerCase(); return d || (f = jb[g], jb[g] = e, e = null != c(a, b, d) ? g : null, jb[g] = f), e } }); var kb = /^(?:input|select|textarea|button)$/i, lb = /^(?:a|area)$/i; r.fn.extend({ prop: function (a, b) { return S(this, r.prop, a, b, arguments.length > 1) }, removeProp: function (a) { return this.each(function () { delete this[r.propFix[a] || a] }) } }), r.extend({ prop: function (a, b, c) { var d, e, f = a.nodeType; if (3 !== f && 8 !== f && 2 !== f) return 1 === f && r.isXMLDoc(a) || (b = r.propFix[b] || b, e = r.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b] }, propHooks: { tabIndex: { get: function (a) { var b = r.find.attr(a, "tabindex"); return b ? parseInt(b, 10) : kb.test(a.nodeName) || lb.test(a.nodeName) && a.href ? 0 : -1 } } }, propFix: { "for": "htmlFor", "class": "className" } }), o.optSelected || (r.propHooks.selected = { get: function (a) { var b = a.parentNode; return b && b.parentNode && b.parentNode.selectedIndex, null }, set: function (a) { var b = a.parentNode; b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex) } }), r.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () { r.propFix[this.toLowerCase()] = this }); function mb(a) { var b = a.match(K) || []; return b.join(" ") } function nb(a) { return a.getAttribute && a.getAttribute("class") || "" } r.fn.extend({ addClass: function (a) { var b, c, d, e, f, g, h, i = 0; if (r.isFunction(a)) return this.each(function (b) { r(this).addClass(a.call(this, b, nb(this))) }); if ("string" == typeof a && a) { b = a.match(K) || []; while (c = this[i++]) if (e = nb(c), d = 1 === c.nodeType && " " + mb(e) + " ") { g = 0; while (f = b[g++]) d.indexOf(" " + f + " ") < 0 && (d += f + " "); h = mb(d), e !== h && c.setAttribute("class", h) } } return this }, removeClass: function (a) { var b, c, d, e, f, g, h, i = 0; if (r.isFunction(a)) return this.each(function (b) { r(this).removeClass(a.call(this, b, nb(this))) }); if (!arguments.length) return this.attr("class", ""); if ("string" == typeof a && a) { b = a.match(K) || []; while (c = this[i++]) if (e = nb(c), d = 1 === c.nodeType && " " + mb(e) + " ") { g = 0; while (f = b[g++]) while (d.indexOf(" " + f + " ") > -1) d = d.replace(" " + f + " ", " "); h = mb(d), e !== h && c.setAttribute("class", h) } } return this }, toggleClass: function (a, b) { var c = typeof a; return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : r.isFunction(a) ? this.each(function (c) { r(this).toggleClass(a.call(this, c, nb(this), b), b) }) : this.each(function () { var b, d, e, f; if ("string" === c) { d = 0, e = r(this), f = a.match(K) || []; while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b) } else void 0 !== a && "boolean" !== c || (b = nb(this), b && V.set(this, "__className__", b), this.setAttribute && this.setAttribute("class", b || a === !1 ? "" : V.get(this, "__className__") || "")) }) }, hasClass: function (a) { var b, c, d = 0; b = " " + a + " "; while (c = this[d++]) if (1 === c.nodeType && (" " + mb(nb(c)) + " ").indexOf(b) > -1) return !0; return !1 } }); var ob = /\r/g; r.fn.extend({ val: function (a) { var b, c, d, e = this[0]; { if (arguments.length) return d = r.isFunction(a), this.each(function (c) { var e; 1 === this.nodeType && (e = d ? a.call(this, c, r(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : r.isArray(e) && (e = r.map(e, function (a) { return null == a ? "" : a + "" })), b = r.valHooks[this.type] || r.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e)) }); if (e) return b = r.valHooks[e.type] || r.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(ob, "") : null == c ? "" : c) } } }), r.extend({ valHooks: { option: { get: function (a) { var b = r.find.attr(a, "value"); return null != b ? b : mb(r.text(a)) } }, select: { get: function (a) { var b, c, d, e = a.options, f = a.selectedIndex, g = "select-one" === a.type, h = g ? null : [], i = g ? f + 1 : e.length; for (d = f < 0 ? i : g ? f : 0; d < i; d++) if (c = e[d], (c.selected || d === f) && !c.disabled && (!c.parentNode.disabled || !r.nodeName(c.parentNode, "optgroup"))) { if (b = r(c).val(), g) return b; h.push(b) } return h }, set: function (a, b) { var c, d, e = a.options, f = r.makeArray(b), g = e.length; while (g--) d = e[g], (d.selected = r.inArray(r.valHooks.option.get(d), f) > -1) && (c = !0); return c || (a.selectedIndex = -1), f } } } }), r.each(["radio", "checkbox"], function () { r.valHooks[this] = { set: function (a, b) { if (r.isArray(b)) return a.checked = r.inArray(r(a).val(), b) > -1 } }, o.checkOn || (r.valHooks[this].get = function (a) { return null === a.getAttribute("value") ? "on" : a.value }) }); var pb = /^(?:focusinfocus|focusoutblur)$/; r.extend(r.event, { trigger: function (b, c, e, f) { var g, h, i, j, k, m, n, o = [e || d], p = l.call(b, "type") ? b.type : b, q = l.call(b, "namespace") ? b.namespace.split(".") : []; if (h = i = e = e || d, 3 !== e.nodeType && 8 !== e.nodeType && !pb.test(p + r.event.triggered) && (p.indexOf(".") > -1 && (q = p.split("."), p = q.shift(), q.sort()), k = p.indexOf(":") < 0 && "on" + p, b = b[r.expando] ? b : new r.Event(p, "object" == typeof b && b), b.isTrigger = f ? 2 : 3, b.namespace = q.join("."), b.rnamespace = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = e), c = null == c ? [b] : r.makeArray(c, [b]), n = r.event.special[p] || {}, f || !n.trigger || n.trigger.apply(e, c) !== !1)) { if (!f && !n.noBubble && !r.isWindow(e)) { for (j = n.delegateType || p, pb.test(j + p) || (h = h.parentNode) ; h; h = h.parentNode) o.push(h), i = h; i === (e.ownerDocument || d) && o.push(i.defaultView || i.parentWindow || a) } g = 0; while ((h = o[g++]) && !b.isPropagationStopped()) b.type = g > 1 ? j : n.bindType || p, m = (V.get(h, "events") || {})[b.type] && V.get(h, "handle"), m && m.apply(h, c), m = k && h[k], m && m.apply && T(h) && (b.result = m.apply(h, c), b.result === !1 && b.preventDefault()); return b.type = p, f || b.isDefaultPrevented() || n._default && n._default.apply(o.pop(), c) !== !1 || !T(e) || k && r.isFunction(e[p]) && !r.isWindow(e) && (i = e[k], i && (e[k] = null), r.event.triggered = p, e[p](), r.event.triggered = void 0, i && (e[k] = i)), b.result } }, simulate: function (a, b, c) { var d = r.extend(new r.Event, c, { type: a, isSimulated: !0 }); r.event.trigger(d, null, b) } }), r.fn.extend({ trigger: function (a, b) { return this.each(function () { r.event.trigger(a, b, this) }) }, triggerHandler: function (a, b) { var c = this[0]; if (c) return r.event.trigger(a, b, c, !0) } }), r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function (a, b) { r.fn[b] = function (a, c) { return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b) } }), r.fn.extend({ hover: function (a, b) { return this.mouseenter(a).mouseleave(b || a) } }), o.focusin = "onfocusin" in a, o.focusin || r.each({ focus: "focusin", blur: "focusout" }, function (a, b) { var c = function (a) { r.event.simulate(b, a.target, r.event.fix(a)) }; r.event.special[b] = { setup: function () { var d = this.ownerDocument || this, e = V.access(d, b); e || d.addEventListener(a, c, !0), V.access(d, b, (e || 0) + 1) }, teardown: function () { var d = this.ownerDocument || this, e = V.access(d, b) - 1; e ? V.access(d, b, e) : (d.removeEventListener(a, c, !0), V.remove(d, b)) } } }); var qb = a.location, rb = r.now(), sb = /\?/; r.parseXML = function (b) { var c; if (!b || "string" != typeof b) return null; try { c = (new a.DOMParser).parseFromString(b, "text/xml") } catch (d) { c = void 0 } return c && !c.getElementsByTagName("parsererror").length || r.error("Invalid XML: " + b), c }; var tb = /\[\]$/, ub = /\r?\n/g, vb = /^(?:submit|button|image|reset|file)$/i, wb = /^(?:input|select|textarea|keygen)/i; function xb(a, b, c, d) { var e; if (r.isArray(b)) r.each(b, function (b, e) { c || tb.test(a) ? d(a, e) : xb(a + "[" + ("object" == typeof e && null != e ? b : "") + "]", e, c, d) }); else if (c || "object" !== r.type(b)) d(a, b); else for (e in b) xb(a + "[" + e + "]", b[e], c, d) } r.param = function (a, b) { var c, d = [], e = function (a, b) { var c = r.isFunction(b) ? b() : b; d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(null == c ? "" : c) }; if (r.isArray(a) || a.jquery && !r.isPlainObject(a)) r.each(a, function () { e(this.name, this.value) }); else for (c in a) xb(c, a[c], b, e); return d.join("&") }, r.fn.extend({ serialize: function () { return r.param(this.serializeArray()) }, serializeArray: function () { return this.map(function () { var a = r.prop(this, "elements"); return a ? r.makeArray(a) : this }).filter(function () { var a = this.type; return this.name && !r(this).is(":disabled") && wb.test(this.nodeName) && !vb.test(a) && (this.checked || !ia.test(a)) }).map(function (a, b) { var c = r(this).val(); return null == c ? null : r.isArray(c) ? r.map(c, function (a) { return { name: b.name, value: a.replace(ub, "\r\n") } }) : { name: b.name, value: c.replace(ub, "\r\n") } }).get() } }); var yb = /%20/g, zb = /#.*$/, Ab = /([?&])_=[^&]*/, Bb = /^(.*?):[ \t]*([^\r\n]*)$/gm, Cb = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, Db = /^(?:GET|HEAD)$/, Eb = /^\/\//, Fb = {}, Gb = {}, Hb = "*/".concat("*"), Ib = d.createElement("a"); Ib.href = qb.href; function Jb(a) { return function (b, c) { "string" != typeof b && (c = b, b = "*"); var d, e = 0, f = b.toLowerCase().match(K) || []; if (r.isFunction(c)) while (d = f[e++]) "+" === d[0] ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c) } } function Kb(a, b, c, d) { var e = {}, f = a === Gb; function g(h) { var i; return e[h] = !0, r.each(a[h] || [], function (a, h) { var j = h(b, c, d); return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1) }), i } return g(b.dataTypes[0]) || !e["*"] && g("*") } function Lb(a, b) { var c, d, e = r.ajaxSettings.flatOptions || {}; for (c in b) void 0 !== b[c] && ((e[c] ? a : d || (d = {}))[c] = b[c]); return d && r.extend(!0, a, d), a } function Mb(a, b, c) { var d, e, f, g, h = a.contents, i = a.dataTypes; while ("*" === i[0]) i.shift(), void 0 === d && (d = a.mimeType || b.getResponseHeader("Content-Type")); if (d) for (e in h) if (h[e] && h[e].test(d)) { i.unshift(e); break } if (i[0] in c) f = i[0]; else { for (e in c) { if (!i[0] || a.converters[e + " " + i[0]]) { f = e; break } g || (g = e) } f = f || g } if (f) return f !== i[0] && i.unshift(f), c[f] } function Nb(a, b, c, d) { var e, f, g, h, i, j = {}, k = a.dataTypes.slice(); if (k[1]) for (g in a.converters) j[g.toLowerCase()] = a.converters[g]; f = k.shift(); while (f) if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift()) if ("*" === f) f = i; else if ("*" !== i && i !== f) { if (g = j[i + " " + f] || j["* " + f], !g) for (e in j) if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) { g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1])); break } if (g !== !0) if (g && a["throws"]) b = g(b); else try { b = g(b) } catch (l) { return { state: "parsererror", error: g ? l : "No conversion from " + i + " to " + f } } } return { state: "success", data: b } } r.extend({ active: 0, lastModified: {}, etag: {}, ajaxSettings: { url: qb.href, type: "GET", isLocal: Cb.test(qb.protocol), global: !0, processData: !0, async: !0, contentType: "application/x-www-form-urlencoded; charset=UTF-8", accepts: { "*": Hb, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, converters: { "* text": String, "text html": !0, "text json": JSON.parse, "text xml": r.parseXML }, flatOptions: { url: !0, context: !0 } }, ajaxSetup: function (a, b) { return b ? Lb(Lb(a, r.ajaxSettings), b) : Lb(r.ajaxSettings, a) }, ajaxPrefilter: Jb(Fb), ajaxTransport: Jb(Gb), ajax: function (b, c) { "object" == typeof b && (c = b, b = void 0), c = c || {}; var e, f, g, h, i, j, k, l, m, n, o = r.ajaxSetup({}, c), p = o.context || o, q = o.context && (p.nodeType || p.jquery) ? r(p) : r.event, s = r.Deferred(), t = r.Callbacks("once memory"), u = o.statusCode || {}, v = {}, w = {}, x = "canceled", y = { readyState: 0, getResponseHeader: function (a) { var b; if (k) { if (!h) { h = {}; while (b = Bb.exec(g)) h[b[1].toLowerCase()] = b[2] } b = h[a.toLowerCase()] } return null == b ? null : b }, getAllResponseHeaders: function () { return k ? g : null }, setRequestHeader: function (a, b) { return null == k && (a = w[a.toLowerCase()] = w[a.toLowerCase()] || a, v[a] = b), this }, overrideMimeType: function (a) { return null == k && (o.mimeType = a), this }, statusCode: function (a) { var b; if (a) if (k) y.always(a[y.status]); else for (b in a) u[b] = [u[b], a[b]]; return this }, abort: function (a) { var b = a || x; return e && e.abort(b), A(0, b), this } }; if (s.promise(y), o.url = ((b || o.url || qb.href) + "").replace(Eb, qb.protocol + "//"), o.type = c.method || c.type || o.method || o.type, o.dataTypes = (o.dataType || "*").toLowerCase().match(K) || [""], null == o.crossDomain) { j = d.createElement("a"); try { j.href = o.url, j.href = j.href, o.crossDomain = Ib.protocol + "//" + Ib.host != j.protocol + "//" + j.host } catch (z) { o.crossDomain = !0 } } if (o.data && o.processData && "string" != typeof o.data && (o.data = r.param(o.data, o.traditional)), Kb(Fb, o, c, y), k) return y; l = r.event && o.global, l && 0 === r.active++ && r.event.trigger("ajaxStart"), o.type = o.type.toUpperCase(), o.hasContent = !Db.test(o.type), f = o.url.replace(zb, ""), o.hasContent ? o.data && o.processData && 0 === (o.contentType || "").indexOf("application/x-www-form-urlencoded") && (o.data = o.data.replace(yb, "+")) : (n = o.url.slice(f.length), o.data && (f += (sb.test(f) ? "&" : "?") + o.data, delete o.data), o.cache === !1 && (f = f.replace(Ab, "$1"), n = (sb.test(f) ? "&" : "?") + "_=" + rb++ + n), o.url = f + n), o.ifModified && (r.lastModified[f] && y.setRequestHeader("If-Modified-Since", r.lastModified[f]), r.etag[f] && y.setRequestHeader("If-None-Match", r.etag[f])), (o.data && o.hasContent && o.contentType !== !1 || c.contentType) && y.setRequestHeader("Content-Type", o.contentType), y.setRequestHeader("Accept", o.dataTypes[0] && o.accepts[o.dataTypes[0]] ? o.accepts[o.dataTypes[0]] + ("*" !== o.dataTypes[0] ? ", " + Hb + "; q=0.01" : "") : o.accepts["*"]); for (m in o.headers) y.setRequestHeader(m, o.headers[m]); if (o.beforeSend && (o.beforeSend.call(p, y, o) === !1 || k)) return y.abort(); if (x = "abort", t.add(o.complete), y.done(o.success), y.fail(o.error), e = Kb(Gb, o, c, y)) { if (y.readyState = 1, l && q.trigger("ajaxSend", [y, o]), k) return y; o.async && o.timeout > 0 && (i = a.setTimeout(function () { y.abort("timeout") }, o.timeout)); try { k = !1, e.send(v, A) } catch (z) { if (k) throw z; A(-1, z) } } else A(-1, "No Transport"); function A(b, c, d, h) { var j, m, n, v, w, x = c; k || (k = !0, i && a.clearTimeout(i), e = void 0, g = h || "", y.readyState = b > 0 ? 4 : 0, j = b >= 200 && b < 300 || 304 === b, d && (v = Mb(o, y, d)), v = Nb(o, v, y, j), j ? (o.ifModified && (w = y.getResponseHeader("Last-Modified"), w && (r.lastModified[f] = w), w = y.getResponseHeader("etag"), w && (r.etag[f] = w)), 204 === b || "HEAD" === o.type ? x = "nocontent" : 304 === b ? x = "notmodified" : (x = v.state, m = v.data, n = v.error, j = !n)) : (n = x, !b && x || (x = "error", b < 0 && (b = 0))), y.status = b, y.statusText = (c || x) + "", j ? s.resolveWith(p, [m, x, y]) : s.rejectWith(p, [y, x, n]), y.statusCode(u), u = void 0, l && q.trigger(j ? "ajaxSuccess" : "ajaxError", [y, o, j ? m : n]), t.fireWith(p, [y, x]), l && (q.trigger("ajaxComplete", [y, o]), --r.active || r.event.trigger("ajaxStop"))) } return y }, getJSON: function (a, b, c) { return r.get(a, b, c, "json") }, getScript: function (a, b) { return r.get(a, void 0, b, "script") } }), r.each(["get", "post"], function (a, b) { r[b] = function (a, c, d, e) { return r.isFunction(c) && (e = e || d, d = c, c = void 0), r.ajax(r.extend({ url: a, type: b, dataType: e, data: c, success: d }, r.isPlainObject(a) && a)) } }), r._evalUrl = function (a) { return r.ajax({ url: a, type: "GET", dataType: "script", cache: !0, async: !1, global: !1, "throws": !0 }) }, r.fn.extend({ wrapAll: function (a) { var b; return this[0] && (r.isFunction(a) && (a = a.call(this[0])), b = r(a, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && b.insertBefore(this[0]), b.map(function () { var a = this; while (a.firstElementChild) a = a.firstElementChild; return a }).append(this)), this }, wrapInner: function (a) { return r.isFunction(a) ? this.each(function (b) { r(this).wrapInner(a.call(this, b)) }) : this.each(function () { var b = r(this), c = b.contents(); c.length ? c.wrapAll(a) : b.append(a) }) }, wrap: function (a) { var b = r.isFunction(a); return this.each(function (c) { r(this).wrapAll(b ? a.call(this, c) : a) }) }, unwrap: function (a) { return this.parent(a).not("body").each(function () { r(this).replaceWith(this.childNodes) }), this } }), r.expr.pseudos.hidden = function (a) { return !r.expr.pseudos.visible(a) }, r.expr.pseudos.visible = function (a) { return !!(a.offsetWidth || a.offsetHeight || a.getClientRects().length) }, r.ajaxSettings.xhr = function () { try { return new a.XMLHttpRequest } catch (b) { } }; var Ob = { 0: 200, 1223: 204 }, Pb = r.ajaxSettings.xhr(); o.cors = !!Pb && "withCredentials" in Pb, o.ajax = Pb = !!Pb, r.ajaxTransport(function (b) { var c, d; if (o.cors || Pb && !b.crossDomain) return { send: function (e, f) { var g, h = b.xhr(); if (h.open(b.type, b.url, b.async, b.username, b.password), b.xhrFields) for (g in b.xhrFields) h[g] = b.xhrFields[g]; b.mimeType && h.overrideMimeType && h.overrideMimeType(b.mimeType), b.crossDomain || e["X-Requested-With"] || (e["X-Requested-With"] = "XMLHttpRequest"); for (g in e) h.setRequestHeader(g, e[g]); c = function (a) { return function () { c && (c = d = h.onload = h.onerror = h.onabort = h.onreadystatechange = null, "abort" === a ? h.abort() : "error" === a ? "number" != typeof h.status ? f(0, "error") : f(h.status, h.statusText) : f(Ob[h.status] || h.status, h.statusText, "text" !== (h.responseType || "text") || "string" != typeof h.responseText ? { binary: h.response } : { text: h.responseText }, h.getAllResponseHeaders())) } }, h.onload = c(), d = h.onerror = c("error"), void 0 !== h.onabort ? h.onabort = d : h.onreadystatechange = function () { 4 === h.readyState && a.setTimeout(function () { c && d() }) }, c = c("abort"); try { h.send(b.hasContent && b.data || null) } catch (i) { if (c) throw i } }, abort: function () { c && c() } } }), r.ajaxPrefilter(function (a) { a.crossDomain && (a.contents.script = !1) }), r.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function (a) { return r.globalEval(a), a } } }), r.ajaxPrefilter("script", function (a) { void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET") }), r.ajaxTransport("script", function (a) { if (a.crossDomain) { var b, c; return { send: function (e, f) { b = r("<script>").prop({ charset: a.scriptCharset, src: a.url }).on("load error", c = function (a) { b.remove(), c = null, a && f("error" === a.type ? 404 : 200, a.type) }), d.head.appendChild(b[0]) }, abort: function () { c && c() } } } }); var Qb = [], Rb = /(=)\?(?=&|$)|\?\?/; r.ajaxSetup({ jsonp: "callback", jsonpCallback: function () { var a = Qb.pop() || r.expando + "_" + rb++; return this[a] = !0, a } }), r.ajaxPrefilter("json jsonp", function (b, c, d) { var e, f, g, h = b.jsonp !== !1 && (Rb.test(b.url) ? "url" : "string" == typeof b.data && 0 === (b.contentType || "").indexOf("application/x-www-form-urlencoded") && Rb.test(b.data) && "data"); if (h || "jsonp" === b.dataTypes[0]) return e = b.jsonpCallback = r.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(Rb, "$1" + e) : b.jsonp !== !1 && (b.url += (sb.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function () { return g || r.error(e + " was not called"), g[0] }, b.dataTypes[0] = "json", f = a[e], a[e] = function () { g = arguments }, d.always(function () { void 0 === f ? r(a).removeProp(e) : a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, Qb.push(e)), g && r.isFunction(f) && f(g[0]), g = f = void 0 }), "script" }), o.createHTMLDocument = function () { var a = d.implementation.createHTMLDocument("").body; return a.innerHTML = "<form></form><form></form>", 2 === a.childNodes.length }(), r.parseHTML = function (a, b, c) { if ("string" != typeof a) return []; "boolean" == typeof b && (c = b, b = !1); var e, f, g; return b || (o.createHTMLDocument ? (b = d.implementation.createHTMLDocument(""), e = b.createElement("base"), e.href = d.location.href, b.head.appendChild(e)) : b = d), f = B.exec(a), g = !c && [], f ? [b.createElement(f[1])] : (f = pa([a], b, g), g && g.length && r(g).remove(), r.merge([], f.childNodes)) }, r.fn.load = function (a, b, c) { var d, e, f, g = this, h = a.indexOf(" "); return h > -1 && (d = mb(a.slice(h)), a = a.slice(0, h)), r.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (e = "POST"), g.length > 0 && r.ajax({ url: a, type: e || "GET", dataType: "html", data: b }).done(function (a) { f = arguments, g.html(d ? r("<div>").append(r.parseHTML(a)).find(d) : a) }).always(c && function (a, b) { g.each(function () { c.apply(this, f || [a.responseText, b, a]) }) }), this }, r.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (a, b) { r.fn[b] = function (a) { return this.on(b, a) } }), r.expr.pseudos.animated = function (a) { return r.grep(r.timers, function (b) { return a === b.elem }).length }; function Sb(a) { return r.isWindow(a) ? a : 9 === a.nodeType && a.defaultView } r.offset = { setOffset: function (a, b, c) { var d, e, f, g, h, i, j, k = r.css(a, "position"), l = r(a), m = {}; "static" === k && (a.style.position = "relative"), h = l.offset(), f = r.css(a, "top"), i = r.css(a, "left"), j = ("absolute" === k || "fixed" === k) && (f + i).indexOf("auto") > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), r.isFunction(b) && (b = b.call(a, c, r.extend({}, h))), null != b.top && (m.top = b.top - h.top + g), null != b.left && (m.left = b.left - h.left + e), "using" in b ? b.using.call(a, m) : l.css(m) } }, r.fn.extend({ offset: function (a) { if (arguments.length) return void 0 === a ? this : this.each(function (b) { r.offset.setOffset(this, a, b) }); var b, c, d, e, f = this[0]; if (f) return f.getClientRects().length ? (d = f.getBoundingClientRect(), d.width || d.height ? (e = f.ownerDocument, c = Sb(e), b = e.documentElement, { top: d.top + c.pageYOffset - b.clientTop, left: d.left + c.pageXOffset - b.clientLeft }) : d) : { top: 0, left: 0 } }, position: function () { if (this[0]) { var a, b, c = this[0], d = { top: 0, left: 0 }; return "fixed" === r.css(c, "position") ? b = c.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), r.nodeName(a[0], "html") || (d = a.offset()), d = { top: d.top + r.css(a[0], "borderTopWidth", !0), left: d.left + r.css(a[0], "borderLeftWidth", !0) }), { top: b.top - d.top - r.css(c, "marginTop", !0), left: b.left - d.left - r.css(c, "marginLeft", !0) } } }, offsetParent: function () { return this.map(function () { var a = this.offsetParent; while (a && "static" === r.css(a, "position")) a = a.offsetParent; return a || qa }) } }), r.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (a, b) { var c = "pageYOffset" === b; r.fn[a] = function (d) { return S(this, function (a, d, e) { var f = Sb(a); return void 0 === e ? f ? f[b] : a[d] : void (f ? f.scrollTo(c ? f.pageXOffset : e, c ? e : f.pageYOffset) : a[d] = e) }, a, d, arguments.length) } }), r.each(["top", "left"], function (a, b) { r.cssHooks[b] = Oa(o.pixelPosition, function (a, c) { if (c) return c = Na(a, b), La.test(c) ? r(a).position()[b] + "px" : c }) }), r.each({ Height: "height", Width: "width" }, function (a, b) { r.each({ padding: "inner" + a, content: b, "": "outer" + a }, function (c, d) { r.fn[d] = function (e, f) { var g = arguments.length && (c || "boolean" != typeof e), h = c || (e === !0 || f === !0 ? "margin" : "border"); return S(this, function (b, c, e) { var f; return r.isWindow(b) ? 0 === d.indexOf("outer") ? b["inner" + a] : b.document.documentElement["client" + a] : 9 === b.nodeType ? (f = b.documentElement, Math.max(b.body["scroll" + a], f["scroll" + a], b.body["offset" + a], f["offset" + a], f["client" + a])) : void 0 === e ? r.css(b, c, h) : r.style(b, c, e, h) }, b, g ? e : void 0, g) } }) }), r.fn.extend({ bind: function (a, b, c) { return this.on(a, null, b, c) }, unbind: function (a, b) { return this.off(a, null, b) }, delegate: function (a, b, c, d) { return this.on(b, a, c, d) }, undelegate: function (a, b, c) { return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c) } }), r.parseJSON = JSON.parse, "function" == typeof define && define.amd && define("jquery", [], function () { return r }); var Tb = a.jQuery, Ub = a.$; return r.noConflict = function (b) { return a.$ === r && (a.$ = Ub), b && a.jQuery === r && (a.jQuery = Tb), r }, b || (a.jQuery = a.$ = r), r
});
jQuery.fn.reverse = function () {
return this.pushStack(this.get().reverse(), arguments);
};
//Version number
var ver = 2.3;
document.title += " v"+ver;
//main js
function configBarSetting() {
this.sidebar = function () {
$('.setting-button').on('click', function (e) {
e.preventDefault();
var target = $(this).attr('href');
$(target).addClass('active');
setColIconsAndPresets("tOptoColour");
setColIconsAndPresets("tBgColour");
$('body').append('<div class="modal-setting"></div>')
});
$('.close').on('click', function (e) {
e.preventDefault();
$('.setting-bar').removeClass('active');
$('.guide-section').removeClass('active');
$('.mask').removeClass('active');
$('.modal-setting').remove();
});
$('.questions-btn').on('click', function (e) {
e.preventDefault();
$('.guide-section').addClass('active');
$('.mask').addClass('active');
});
$('.close-guide').on('click', function (e) {
e.preventDefault();
$('.guide-section').removeClass('active');
$('.mask').removeClass('active');
});
$('body').on('click', function (e) {
});
$(document).on('click', '.modal-setting', function () {
$('.setting-bar').removeClass('active');
$('.guide-section').removeClass('active');
$('.mask').removeClass('active');
$('.modal-setting').remove();
});
//allow colour preset buttons to update colour field and icon
$('.col-preset-opto').on('click', function (e) {
e.preventDefault();
$('.col-preset-opto').removeClass('disabled-btn');
$(this).addClass('disabled-btn');
$('#tOptoColour').val(e.target.value);
$('#tOptoColour ~ i').css('background',e.target.value);
});
$('.col-preset-bg').on('click', function (e) {
e.preventDefault();
$('.col-preset-bg').removeClass('disabled-btn');
$(this).addClass('disabled-btn');
$('#tBgColour').val(e.target.value);
$('#tBgColour ~ i').css('background',e.target.value);
});
//set the icon colours, enable/disable preset buttons
function setColIconsAndPresets (id) {
var box = $('#'+id);
box.next('i').css('background',box.val());
var presets = (id.includes("Opto")) ? ".col-preset-opto" : ".col-preset-bg";
$(presets).each(function(idx,el) {
$(el).removeClass('disabled-btn');
if (el.value == box.val()) {
$(el).addClass('disabled-btn');
}
});
}
//on updating colour fields, update icon and preset buttons
$('.col-setting input').on('change', function (e) {
e.preventDefault();
var colInput = $(this).attr('id');
setColIconsAndPresets(colInput);
});
//let filter colour sliders update the slider background
$('.slider').on('input', function (e) {
e.preventDefault;
var slider = $(this);
slider.css('background','hsl('+slider.val()+',80%,60%)');
})
//disable background colour fg when Vanishing Sloan is selected
$('#sOptotype').on('change', function (e) {
if (this.value == 5) {
$('#fgBgColour').removeClass('disabled-fg').addClass('disabled-fg');
$('#fgPresetsBg').removeClass('disabled-fg').addClass('disabled-fg');
} else {
$('#fgBgColour').removeClass('disabled-fg');
$('#fgPresetsBg').removeClass('disabled-fg');
}
});
};
this.accordion = function () {
// panel title click
$('.panel-heading').on('click', function (e) {
e.preventDefault();
var target = $(this).next();
if (!$(target).is(":visible")) {
$('.panel-heading').removeClass('active');
$(this).toggleClass('active');
$('.panel-collapse').slideUp();
$(target).slideDown();
}
});
// question icon click
$('.questions-btn').on('click', function (e) {
e.preventDefault();
var target = $(this).attr('href');
var content = $(target).next();
if (!$(content).is(":visible")) {
$('.panel-heading').removeClass('active');
$('.panel-collapse').slideUp();
$(target).addClass('active');
$(content).slideDown();
}
});
};
this.init = function () {
this.sidebar();
this.accordion();
}
};
function ConfigWolfChart() {
var objWolf = {};
var notation, viewWidth, viewHeight = document.documentElement.clientHeight, numeratorType, oldCharacter = [];
var chartArray = [], timeOut;
var anims = ['slide-out-top','slide-out-right','slide-out-bottom','slide-out-left','slide-in-top','slide-in-right','slide-in-bottom','slide-in-left'];
var colours = {
optotype: "",
backgrounds: {
optotype: "",
binocular: "",
},
fRedHue: "",
fGreenHue: "",
themes: {
R: 'rgb(174,39,96)',
B: 'rgb(104,154,104)',
M: 'rgb(214, 116, 10)',
},
}
var shortcuts = ['u','n','g','k','q','z'];
this.UpdateObjWolf = function () {
objWolf = {
dateCreated : Date.now(),
useCountTimer : null,
catsLength : 0,
catThis : "",
chartThis : "",
chartThisId : "",
//array of charts with spacebar functions, and the function type
hasSBFunc : [['rJCCDots','zoom'], ['rBullseye','zoom'], ['rSeptumChart','interspace'], ['bFixDisp','rotate'], ['bWorth4Dot','zoom'], ['mWhiteDot','zoom']],
pointer : 0,
animIn : "",
animOut : "",
catLeft : function () {
return (this.catThis>0) ? this.catThis-1 : this.catsLength-1;
},
catRight : function () {
return (this.catThis==this.catsLength-1) ? 0 : this.catThis+1;
},
chartU : function() {
return (this.chartThis<this[this.catThis].arCharts.length-1) ? this.chartThis+1 : 0;
},
chartD: function () {
return (this.chartThis>0) ? this.chartThis-1 : this[this.catThis].arCharts.length-1;
},
setUseCount : function (cat,id) {
//increment the useCount of the chart up one
var obj = this[cat].arCharts[id];
obj.useCount++;
},
getLastUsed : function (cat) {
return this[cat].lastUsed;
},
getMostUsed : function (cat) {
//calculate most browsed in the category
var max = -1, result = "";
var ar = this[cat].arCharts;
ar.forEach(function(el,idx) {
if (el.useCount > max) {
max = el.useCount;
result = idx;
}
});
return result;
},
cycler : function (idx,len) {
(idx<len-1) ? idx++ : idx = 0;
return idx;
}
}
}
this.Clock = function () {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = (m<10) ? "0"+m : m;
$('#clock-div').html(h + ":" + m);
var t = setTimeout(functionConfigWolfChart.Clock, 1000);
}
this.DisplayArrows = function () {
/*Charts are arranged in categories. User navigates left
and right between categories, and up and down within
categories.
Navigation links are built from the array of categories
and the categories are populated by divs in this page
(and later from external files also).
*/
//populate the arrow-button-div with arrows
$('.arrow-button-prototype').clone().appendTo('#btRight').attr({class:'arrow-button'}).on('click', function () {functionConfigWolfChart.navCat(objWolf.catRight(),'right')});
$('.arrow-button-prototype').clone().appendTo('#btLeft').css('transform','rotate(180deg)').attr({class:'arrow-button'}).on('click', function () {functionConfigWolfChart.navCat(objWolf.catLeft(),'left')});
$('.arrow-button-prototype').clone().appendTo('#btUp').css('transform','rotate(-90deg)').attr({class:'arrow-button', id:'up-arrow'}).on('click', function () {functionConfigWolfChart.scrollChart(objWolf.catThis,objWolf.chartU(),'top')});
$('.arrow-button-prototype').clone().appendTo('#btDn').css('transform','rotate(90deg)').attr({class:'arrow-button', id:'dn-arrow'}).on('click', function () {functionConfigWolfChart.scrollChart(objWolf.catThis,objWolf.chartD(),'bottom')});
//$('.nav-button-prototype').clone().appendTo('#thisBadge').attr({class:''});
$('.up-arrow-prototype').clone().appendTo('#btUp').attr({class:'pic-arrow', id:'up-pic-arrow'}).css({
width: '100%',
left: '0px',
top: '0px',
}).on('click', function () {functionConfigWolfChart.scrollChart(objWolf.catThis,objWolf.chartU(),'top')});
$('.dn-arrow-prototype').clone().appendTo('#btDn').attr({class:'pic-arrow', id:'dn-pic-arrow'}).css({
width: '100%',
left: '0px',
bottom: '0px',
}).on('click', function () {functionConfigWolfChart.scrollChart(objWolf.catThis,objWolf.chartD(),'bottom')});
//populate the function-button-div with function buttons
$('.zoom-button-prototype').clone().appendTo('#btSpacebarFunc').attr({class:'f-button zoom-button'}).hide();
$('.rotate-button-prototype').clone().appendTo('#btSpacebarFunc').attr({class:'f-button rotate-button'}).hide();
$('.interspace-button-prototype').clone().appendTo('#btSpacebarFunc').attr({class:'f-button interspace-button'}).hide();
$('.shuffle-button-prototype').clone().appendTo('#btShuffleFunc').attr({class: 'f-button shuffle-button' }).on('click', function () {
functionConfigWolfChart.shuffleLetters();
}).hide();
$('.bg-button-prototype').clone().appendTo('#btBgFunc').attr({class: 'f-button bg-button'}).on('click',function () {functionConfigWolfChart.duoBGFunction()}).hide();
//Hover function for buttons
$('.arrow-active').hide();
//mediaMatch here to set hover only for desktopdu
$('.arrow-button, .pic-arrow, .f-button').hover(function() {
$(this).find('.arrow-active').show();
}, function () {$(this).find('.arrow-active').hide();});
//animate flyout nav bar - also animated by mousenter below
$('#nav-button-div').on('click',expand);
function collapse(e) {
var el = $(e.currentTarget);
el.removeClass('expanded');
el.off('click').on('click',expand);
}
function expand(e) {
var el = $(e.currentTarget);
el.addClass('expanded');
el.off('click').on('click',collapse);
timer(parkFlyout, 3000);
}
function parkFlyout() {
$('#nav-button-div').removeClass('expanded');
//navDiv.className = '';
}
function timer(fn, secs) {
clearTimeout(timeOut);
timeOut = setTimeout(fn, secs);
}
$('#nav-button-outer-div').on('mouseenter', function () {
$('#nav-button-div').addClass('expanded');
timer(parkFlyout, 3000);
});
}
this.DisplayNavigations = function () {
var callBackFunction = this;
for (r=0;r<objWolf.catsLength;r++) {
var thing = objWolf[r];
//populate the nav-button-div with category links
$('#nav-button-div').append("<a class='nav-link' id='bt" + thing.cat + "' title='" + thing.title + "'></a>");
$('#bt' + thing.cat).on('click', {id: r}, function (event) {
var data = event.data;
functionConfigWolfChart.navCat(data.id,'fav');
});
$('.nav-button-prototype').clone().appendTo('#bt' + thing.cat).attr({ class: 'nav-button' }).css({ marginBottom: '10px' });
$('#bt' + thing.cat + ' .dot').attr({ fill: thing.col });
$('#bt' + thing.cat + ' svg text').text(thing.cat);
$('.dot-active').hide();
$('.nav-button').hover(function () {
$(this).find('.dot-active').show();
}, function () { $(this).find('.dot-active').hide(); });
}
}
this.sidebarControls = function (selCat, selChart) {
var callBackFunction = this;
var thisLink = $('#bt'+objWolf[selCat].cat);
var thisCol = objWolf[selCat].col;
$('#nav-button-div a').css('background-color','transparent');
thisLink.css('background-color','rgb(102,102,102)');
//select and colour the arrows
if(selCat == 0) {
$('#up-pic-arrow, #dn-pic-arrow').hide();
$('#up-arrow, #dn-arrow').show();
} else {
$('#up-pic-arrow, #dn-pic-arrow').show();
$('#up-arrow, #dn-arrow').hide();
}
$('#btUp,#btDn').find('.arrow-dot').attr({fill:thisCol});
$('#btUp,#btDn').find('.pic-border').attr({stroke:thisCol});
$('#thisBadge').find('svg text').text(objWolf[selCat].cat).attr({fill:thisCol});
$('#thisBadge').find('.dot').attr({fill:'white',opacity:'80%',stroke:thisCol,'stroke-width':'0.25px'});
$('#btLeft .arrow-dot').attr({fill:thisCol});
$('#btRight .arrow-dot').attr({fill:thisCol});
//display the single charts above and below the current in the pic-arrows
$('.scrollPic').remove();
var chartUId = objWolf[selCat].cat+objWolf.chartU(), chartDId = objWolf[selCat].cat+objWolf.chartD();
if(selCat!=0) {
var upArrowInsLayer = $('#up-pic-arrow').find('.up-arrow-g1');
var upArrowPanel = $('#up-pic-arrow').find('.up-arrow-g0 path');
var upMiniChart = $('#' + chartUId);
upMiniChart.find('svg').clone().appendTo(upArrowInsLayer).attr({
width: '80%',
x: '10%',
y: '-10%',
class:'scrollPic',
transform: '',
height: '80%',
}).show();
upArrowPanel.attr('fill',upMiniChart.css('background-color'));
var dnArrowInsLayer = $('#dn-pic-arrow').find('.dn-arrow-g1');
var dnArrowPanel = $('#dn-pic-arrow').find('.dn-arrow-g0 path');
var dnMiniChart = $('#' + chartDId);
dnMiniChart.find('svg').clone().appendTo(dnArrowInsLayer).attr({
width: '80%',
x: '10%',
y: '30%',
class:'scrollPic',
transform: '',
height: '80%',
}).show();
dnArrowPanel.attr('fill',dnMiniChart.css('background-color'));
}
//select ánd configure the buttons for this category
if(objWolf.catThis==0) {
$('.f-button').hide();
$('.bg-button').show();
$('.shuffle-button').show();
} else {
$('.f-button').hide();
$('.bg-button').hide();
$('.shuffle-button').hide();
// display a space bar function button
var thisChart = objWolf[selCat].arCharts[selChart], thisSVG = $('#' + thisChart.id).find('svg');
if (thisSVG.length > 0) {
objWolf.hasSBFunc.forEach(function (el, idx) {
if (thisSVG[0].id == el[0]) {
var sbfb = $('.'+el[1]+'-button');
var buttonLayers = sbfb.find('g');
sbfb.show();
//set function button state
if(thisChart.isToggled){$(buttonLayers[0]).hide();$(buttonLayers[1]).show();}
else {$(buttonLayers[0]).show();$(buttonLayers[1]).hide();}
//special case for Worth4Dot, where zoom is in reverse - default is double-size
if(thisSVG[0].id == "bWorth4Dot") {$(buttonLayers[0]).hide();$(buttonLayers[1]).show();}
sbfb.off('click').on('click', function () { $("#" + objWolf.chartThisId).trigger('click'); })
}
});
}
}
}
this.navCat = function (selCat,anim) {
objWolf.catThis = selCat;
var thisCat = objWolf[selCat].cat;
if (!anim) {//anim=null is only used on initiating the chart
var arCharts = objWolf[selCat].arCharts;
if(displayOrder == 2 || displayOrder == 3){
objWolf.chartThis = arCharts.length-1;
} else {
objWolf.chartThis = 0;
}
} else if (anim == 'fav') {//nav buttons display most used chart in category
objWolf.chartThis = objWolf.getMostUsed(selCat);
} else {//arrow buttons display last used chart in category
objWolf.chartThis = objWolf.getLastUsed(selCat);
}
functionConfigWolfChart.scrollChart(objWolf.catThis,objWolf.chartThis,anim);
}
this.scrollChart = function (selCat,selChart,anim) {
//select charts from the divs in page
//also here we can pull charts from
//external files.
var functionConfigWolfChart = this;
if(selCat == 0) {
$('#otherChart').hide();
$('#letterChart').show();
} else {
$('#letterChart').hide();
$('#otherChart').show();
}
var charts = $('.'+objWolf[selCat].cat);
switch (anim) {
case "top":
objWolf.animOut = "slide-out-bottom"
break;
case "bottom":
objWolf.animOut = "slide-out-top"
break;
case "left":
objWolf.animOut = "slide-out-right"
break;
case "right":
objWolf.animOut = "slide-out-left"
break;
}
//When animating charts in and out, start sliding in the new chart
//shortly after starting to slide out the old chart, rather than waiting til
//slide out has finished. Then configure the sidebar controls when new chart
//has finished sliding in
if(anim != null) {//after first use
var outGoingChart = $('#'+objWolf.chartThisId);
var inComingChart = $('#'+charts[selChart].id);
$('#otherChart').css({
'background-color': inComingChart.css('background-color'),
})
if(anim !='fav') {//using arrow buttons
objWolf.animIn = 'slide-in-'+anim;
var animPromise = new Promise (function (resolve, reject) {
outGoingChart.removeClass(anims.join(' ')).addClass(objWolf.animOut);
outGoingChart.on('animationstart',resolve());
});
animPromise.then(
function() {
setTimeout(function() {
outGoingChart.removeClass(anims.join(' ')).hide();
inComingChart.addClass(objWolf.animIn).show();
functionConfigWolfChart.sidebarControls(selCat,selChart);
},200);
},
function() {
console.log("something went wrong with the animations");
}
);
} else {//using navigation buttons
outGoingChart.removeClass(anims.join(' ')).hide();
inComingChart.show();
functionConfigWolfChart.sidebarControls(selCat,selChart);
}
} else {//first use
$(charts[selChart]).show();
functionConfigWolfChart.sidebarControls(selCat,selChart);
}
//navigation to and display of chart is now finished
//update cat and chartThis
objWolf.chartThis = selChart;
objWolf.chartThisId = charts[selChart].id;
objWolf[selCat].lastUsed = selChart;
//select animation script for any charts that are animated external to their svg
var thisSVG = $('#' + objWolf.chartThisId).find('svg');
if(thisSVG.parent().hasClass('animated')) {
switch (thisSVG.attr('id')) {
case 'mLetterMorph':
functionConfigWolfChart.letterMorph();
break;
}
}
//record a use count for this chart after n seconds
var timer = objWolf.useCountTimer;
if(timer){clearTimeout(timer);}
objWolf.useCountTimer = setTimeout(function () {objWolf.setUseCount(selCat,selChart);}, 3000);
}
this.SelectOptotype = function () {
$('#sOptotype').on('change', function () {
var optotype = $(this).val();
$('#sAlphabet').html('');
switch (optotype) {
case '1':
$('#sAlphabet').append('<option value="2">BS4274.3</option><option value="1">SnellenU</option>')
break;
case '2':
$('#sAlphabet').append('<option value="3">ETDRS</option><option value="4">SloanU</option>');
break;
case '3':
$('#sAlphabet').append('<option value="5">Landolt_5Chars_01</option>');
break;
case '4':
$('#sAlphabet').append('<option value="6">Tumbling_5Chars_01</option>');
break;
case '5':
$('#sAlphabet').append('<option value="7">Vanishing_5Chars_01</option>');
break;
case '6':
$('#sAlphabet').append('<option value="8">Shapes_5Chars_01</option>');
break;
case '7':
$('#sAlphabet').append('<option value="9">Chinese_5Chars_01</option>');
break;
case '8':
$('#sAlphabet').append('<option value="10">Arabic_5chars_01</option>');
break;
case '9':
$('#sAlphabet').append('<option value="11">Hebrew_5Chars_01</option>');
break;
/* case '10':
$('#sAlphabet').append('<option value="13">Crowded HOTV 3</option><option value="12">Crowded HOTV 1</option>');
break; */
}
});
};
//separating rgb from opacity allows letters to have overlapping elements
this.SetColorCharacter = function (optoCol) {
var rgba = optoCol.replace(/[^\d.,]/g, '').split(',');
var colorRGB = "rgb(" + rgba[0] + "," + rgba[1] + "," + rgba[2] + ")";
var dotA = (parseInt(rgba[3])+1)*0.5;
$('#list-character').find('svg.optotype-symbol').css('opacity', rgba[3]);
//only update fill of black fills, or Vanishing optotypes won't work
$('#list-character').find('svg.optotype-symbol').find('path').not('.white').css({fill: colorRGB});
$('#list-character').find('svg.optotype-symbol').find('polygon').not('.white').css({fill: colorRGB});
$('.guide-dot').css({opacity: dotA,});
};
this.SetBgColor = function (bgCol) {
var rgba = bgCol.replace(/[^\d.,]/g, '').split(',');
var halftone = colours.optotype.replace(/[\d\.]+\)$/g, '0.5');
if(alphabetType==7){//Vanishing optotype needs background same color and half the opacity of the optotype color
$(document.body).css('background-color',halftone);
}
else {
$(document.body).css('background-color',bgCol);
}
};
this.SetHeightCharacter = function (distance) {
var lolb = $('#iLengOfLine').val();//get length of line below
var countArr = -1;
for (d = 0; d < chartArray.length; d++) {
countArr++;
var letterSubtense = chartArray[d][0] * 5; //all letters 5 limbs high
var degrees = letterSubtense / 60;
var radians = degrees * (Math.PI / 180);
var tanNumber = (Math.tan(radians));
var minCharacter = tanNumber * distance * (120 / lolb); // 120 because calibration line is 120 mm
chartArray[d].push(minCharacter);
};
};
this.CaculatorCharacterHeight = function (numeratorType) {
//sets the VA value to be displayed in scoreBox div
var setHeightFunction = this;
var dist = $('#iDistance').val();
switch (notation) {
case "1"://metres
var ar = [0.501, 0.631, 0.794, 1, 1.259, 1.585, 2, 2.512, 3.162, 3.981, 5.012, 6.31, 7.943, 10];
//always input mm
if (numeratorType == "2") {
var scoreDisplay = ['6/3', '6/3.8', '6/4.8', '6/6', '6/7.5', '6/9.5', '6/12', '6/15', '6/19', '6/24', '6/30', '6/38', '6/48', '6/60'];
for (a = 0; a < ar.length; a++) {
chartArray[a] = [ar[a], scoreDisplay[a]];
}
}
else {
var numerator = Math.round(dist / 100) / 10;
for (a = 0; a < ar.length; a++) {
if (a<6){
var score = Math.round(ar[a] * numerator * 10) / 10;
} else {
var score = Math.round(ar[a] * numerator);
}
var str = numerator + "!" + score;
chartArray[a] = [ar[a], str];
}
}
break;
case "2"://feet
var ar = [0.501, 0.631, 0.794, 1, 1.259, 1.585, 2, 2.512, 3.162, 3.981, 5.012, 6.31, 7.943, 10];
if (numeratorType == "2") {
var scoreDisplay = ['20/10', '20/12.5', '20/16', '20/20', '20/25', '20/32', '20/40', '20/50', '20/63', '20/80', '20/100', '20/125', '20/160', '20/200'];
for (a = 0; a < ar.length; a++) {
chartArray[a] = [ar[a], scoreDisplay[a]];
}
}
else {
var numerator = Math.round(dist * 3.28084 / 500)/2;
for (a = 0; a < ar.length; a++) {
var score = Math.round(ar[a] * numerator);
var str = numerator + "!" + score;
chartArray[a] = [ar[a], str];
}
}
break;
case "3"://logMar
var ar = [0.501, 0.631, 0.794, 1, 1.259, 1.585, 2, 2.512, 3.162, 3.981, 5.012, 6.31, 7.943, 10];
var scoreDisplay = ['-0.3', '-0.2', '-0.1', '0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1'];
for (a = 0; a < ar.length; a++) {
chartArray[a] = [ar[a], scoreDisplay[a]];
}
break;
case "4"://Decimal
var ar = [0.501, 0.631, 0.794, 1, 1.259, 1.585, 2, 2.512, 3.162, 3.981, 5.012, 6.31, 7.943, 10];
var scoreDisplay = ['2', '1.6', '1.25', '1', '0.8', '0.63', '0.5', '0.4', '0.32', '0.25', '0.2', '0.16', '0.125', '0.1'];
for (a = 0; a < ar.length; a++) {
chartArray[a] = [ar[a], scoreDisplay[a]];
}
break;
}
//set height for character
setHeightFunction.SetHeightCharacter(dist)
};
this.GenerateCharacter = function (alphabetType,localOptotype) {
var arrayCharacter = [],
convertFunction = this;
switch (alphabetType) {
//set alphabet for each optotype
case '1'://SnellenU
arrayCharacter = ['Snellen_N,Snellen_L,Snellen_A,Snellen_Y,Snellen_Z', 'Snellen_E,Snellen_F,Snellen_R,Snellen_D,Snellen_U', 'Snellen_T,Snellen_P,Snellen_V,Snellen_H,Snellen_X', 'Snellen_Y,Snellen_E,Snellen_L,Snellen_R,Snellen_T', 'Snellen_F,Snellen_X,Snellen_U,Snellen_D,Snellen_H', 'Snellen_A,Snellen_N,Snellen_P,Snellen_V,Snellen_Z', 'Snellen_H,Snellen_Z,Snellen_T,Snellen_Y,Snellen_D', 'Snellen_V,Snellen_F,Snellen_X,Snellen_N,Snellen_R', 'Snellen_A,Snellen_L,Snellen_P,Snellen_U,Snellen_E', 'Snellen_P,Snellen_U,Snellen_V,Snellen_F,Snellen_Y', 'Snellen_T,Snellen_A,Snellen_H,Snellen_E,Snellen_D', 'Snellen_L,Snellen_R,Snellen_N,Snellen_Z,Snellen_X', 'Snellen_D,Snellen_Y,Snellen_P,Snellen_L,Snellen_N', 'Snellen_Z,Snellen_A,Snellen_T,Snellen_F,Snellen_R']
break;
case '2'://BS4274.3
arrayCharacter = ['Snellen_U,Snellen_R,Snellen_N,Snellen_D,Snellen_V', 'Snellen_N,Snellen_F,Snellen_R,Snellen_Z,Snellen_E', 'Snellen_P,Snellen_H,Snellen_D,Snellen_F,Snellen_V', 'Snellen_R,Snellen_U,Snellen_N,Snellen_E,Snellen_Z', 'Snellen_D,Snellen_V,Snellen_E,Snellen_P,Snellen_R', 'Snellen_U,Snellen_D,Snellen_H,Snellen_V,Snellen_N', 'Snellen_Z,Snellen_U,Snellen_V,Snellen_F,Snellen_P', 'Snellen_E,Snellen_R,Snellen_D,Snellen_H,Snellen_Z', 'Snellen_U,Snellen_D,Snellen_P,Snellen_N,Snellen_F', 'Snellen_V,Snellen_E,Snellen_H,Snellen_U,Snellen_P', 'Snellen_F,Snellen_Z,Snellen_V,Snellen_R,Snellen_N', 'Snellen_H,Snellen_R,Snellen_E,Snellen_Z,Snellen_D', 'Snellen_N,Snellen_F,Snellen_H,Snellen_P,Snellen_Z', 'Snellen_U,Snellen_V,Snellen_F,Snellen_E,Snellen_H']
break;
case '3':
arrayCharacter = ['Sloan_C,Sloan_H,Sloan_N,Sloan_R,Sloan_V', 'Sloan_D,Sloan_K,Sloan_O,Sloan_S,Sloan_V', 'Sloan_V,Sloan_O,Sloan_R,Sloan_D,Sloan_N', 'Sloan_H,Sloan_Z,Sloan_C,Sloan_K,Sloan_X', 'Sloan_O,Sloan_K,Sloan_V,Sloan_H,Sloan_D', 'Sloan_Z,Sloan_R,Sloan_N,Sloan_S,Sloan_C', 'Sloan_K,Sloan_S,Sloan_D,Sloan_C,Sloan_H', 'Sloan_R,Sloan_N,Sloan_O,Sloan_V,Sloan_Z', 'Sloan_D,Sloan_H,Sloan_R,Sloan_O,Sloan_K', 'Sloan_C,Sloan_N,Sloan_Z,Sloan_S,Sloan_V', 'Sloan_H,Sloan_O,Sloan_S,Sloan_D,Sloan_N', 'Sloan_C,Sloan_V,Sloan_K,Sloan_Z,Sloan_R', 'Sloan_D,Sloan_H,Sloan_R,Sloan_N,Sloan_O', 'Sloan_S,Sloan_V,Sloan_C,Sloan_K,Sloan_Z']
break;
case '4':
arrayCharacter = ['Sloan_V,Sloan_N,Sloan_T,Sloan_C,Sloan_E', 'Sloan_P,Sloan_X,Sloan_R,Sloan_Z,Sloan_S', 'Sloan_D,Sloan_H,Sloan_O,Sloan_L,Sloan_K', 'Sloan_E,Sloan_T,Sloan_K,Sloan_O,Sloan_D', 'Sloan_C,Sloan_S,Sloan_N,Sloan_R,Sloan_H', 'Sloan_P,Sloan_L,Sloan_X,Sloan_Z,Sloan_V', 'Sloan_N,Sloan_K,Sloan_Z,Sloan_P,Sloan_O', 'Sloan_E,Sloan_V,Sloan_R,Sloan_X,Sloan_D', 'Sloan_T,Sloan_C,Sloan_S,Sloan_L,Sloan_H', 'Sloan_V,Sloan_H,Sloan_X,Sloan_D,Sloan_S', 'Sloan_R,Sloan_O,Sloan_K,Sloan_L,Sloan_E', 'Sloan_Z,Sloan_P,Sloan_C,Sloan_N,Sloan_T', 'Sloan_T,Sloan_E,Sloan_V,Sloan_C,Sloan_R', 'Sloan_H,Sloan_L,Sloan_D,Sloan_P,Sloan_N']
break;
case '5':
arrayCharacter = ['LandoltC_N,LandoltC_S,LandoltC_E,LandoltC_N,LandoltC_W', 'LandoltC_E,LandoltC_E,LandoltC_N,LandoltC_W,LandoltC_S', 'LandoltC_E,LandoltC_S,LandoltC_S,LandoltC_W,LandoltC_N', 'LandoltC_N,LandoltC_W,LandoltC_N,LandoltC_S,LandoltC_E', 'LandoltC_S,LandoltC_W,LandoltC_N,LandoltC_W,LandoltC_E', 'LandoltC_W,LandoltC_E,LandoltC_S,LandoltC_N,LandoltC_S', 'LandoltC_W,LandoltC_N,LandoltC_E,LandoltC_S,LandoltC_W', 'LandoltC_S,LandoltC_N,LandoltC_N,LandoltC_W,LandoltC_E', 'LandoltC_N,LandoltC_E,LandoltC_S,LandoltC_W,LandoltC_W', 'LandoltC_N,LandoltC_S,LandoltC_E,LandoltC_N,LandoltC_W', 'LandoltC_E,LandoltC_E,LandoltC_N,LandoltC_W,LandoltC_S', 'LandoltC_E,LandoltC_S,LandoltC_S,LandoltC_W,LandoltC_N', 'LandoltC_N,LandoltC_W,LandoltC_N,LandoltC_S,LandoltC_E', 'LandoltC_S,LandoltC_W,LandoltC_N,LandoltC_W,LandoltC_E']
break;
case '6':
arrayCharacter = ['TumblingE_N,TumblingE_S,TumblingE_E,TumblingE_N,TumblingE_W', 'TumblingE_E,TumblingE_E,TumblingE_N,TumblingE_W,TumblingE_S', 'TumblingE_E,TumblingE_S,TumblingE_S,TumblingE_W,TumblingE_N', 'TumblingE_N,TumblingE_W,TumblingE_N,TumblingE_S,TumblingE_E', 'TumblingE_S,TumblingE_W,TumblingE_N,TumblingE_W,TumblingE_E', 'TumblingE_W,TumblingE_E,TumblingE_S,TumblingE_N,TumblingE_S', 'TumblingE_W,TumblingE_N,TumblingE_E,TumblingE_S,TumblingE_W', 'TumblingE_S,TumblingE_N,TumblingE_N,TumblingE_W,TumblingE_E', 'TumblingE_N,TumblingE_E,TumblingE_S,TumblingE_W,TumblingE_W', 'TumblingE_N,TumblingE_S,TumblingE_E,TumblingE_N,TumblingE_W', 'TumblingE_E,TumblingE_E,TumblingE_N,TumblingE_W,TumblingE_S', 'TumblingE_E,TumblingE_S,TumblingE_S,TumblingE_W,TumblingE_N', 'TumblingE_N,TumblingE_W,TumblingE_N,TumblingE_S,TumblingE_E', 'TumblingE_S,TumblingE_W,TumblingE_N,TumblingE_W,TumblingE_E'];
break;
case '7':
arrayCharacter = ['VanSloan_C,VanSloan_H,VanSloan_N,VanSloan_R,VanSloan_V', 'VanSloan_D,VanSloan_K,VanSloan_O,VanSloan_S,VanSloan_V', 'VanSloan_V,VanSloan_O,VanSloan_R,VanSloan_D,VanSloan_N', 'VanSloan_H,VanSloan_Z,VanSloan_C,VanSloan_K,VanSloan_X', 'VanSloan_O,VanSloan_K,VanSloan_V,VanSloan_H,VanSloan_D', 'VanSloan_Z,VanSloan_R,VanSloan_N,VanSloan_S,VanSloan_C', 'VanSloan_K,VanSloan_S,VanSloan_D,VanSloan_C,VanSloan_H', 'VanSloan_R,VanSloan_N,VanSloan_O,VanSloan_V,VanSloan_Z', 'VanSloan_D,VanSloan_H,VanSloan_R,VanSloan_O,VanSloan_K', 'VanSloan_C,VanSloan_N,VanSloan_Z,VanSloan_S,VanSloan_V', 'VanSloan_H,VanSloan_O,VanSloan_S,VanSloan_D,VanSloan_N', 'VanSloan_C,VanSloan_V,VanSloan_K,VanSloan_Z,VanSloan_R', 'VanSloan_D,VanSloan_H,VanSloan_R,VanSloan_N,VanSloan_O', 'VanSloan_S,VanSloan_V,VanSloan_C,VanSloan_K,VanSloan_Z'];
break;
case '8':
arrayCharacter = ['Shape5_0,Shape5_3,Shape5_1,Shape5_4,Shape5_2','Shape5_1,Shape5_2,Shape5_0,Shape5_3,Shape5_4','Shape5_4,Shape5_0,Shape5_2,Shape5_1,Shape5_3','Shape5_2,Shape5_3,Shape5_1,Shape5_4,Shape5_0','Shape5_1,Shape5_4,Shape5_3,Shape5_0,Shape5_2','Shape5_3,Shape5_0,Shape5_4,Shape5_2,Shape5_1','Shape5_2,Shape5_1,Shape5_0,Shape5_4,Shape5_3','Shape5_0,Shape5_2,Shape5_1,Shape5_3,Shape5_4','Shape5_3,Shape5_1,Shape5_0,Shape5_4,Shape5_2','Shape5_4,Shape5_0,Shape5_2,Shape5_3,Shape5_1','Shape5_2,Shape5_4,Shape5_3,Shape5_1,Shape5_0','Shape5_1,Shape5_3,Shape5_4,Shape5_0,Shape5_2','Shape5_0,Shape5_4,Shape5_2,Shape5_1,Shape5_3','Shape5_4,Shape5_1,Shape5_3,Shape5_0,Shape5_2'];
break;
case '9':
arrayCharacter = ['Chinese01_0,Chinese01_1,Chinese01_6,Chinese01_3,Chinese01_2','Chinese01_3,Chinese01_2,Chinese01_4,Chinese01_8,Chinese01_7','Chinese01_6,Chinese01_9,Chinese01_5,Chinese01_0,Chinese01_1','Chinese01_4,Chinese01_3,Chinese01_0,Chinese01_7,Chinese01_9','Chinese01_8,Chinese01_1,Chinese01_2,Chinese01_5,Chinese01_6','Chinese01_9,Chinese01_8,Chinese01_6,Chinese01_4,Chinese01_0','Chinese01_1,Chinese01_7,Chinese01_3,Chinese01_9,Chinese01_5','Chinese01_5,Chinese01_0,Chinese01_2,Chinese01_7,Chinese01_8','Chinese01_6,Chinese01_3,Chinese01_8,Chinese01_4,Chinese01_1','Chinese01_2,Chinese01_4,Chinese01_1,Chinese01_7,Chinese01_9','Chinese01_8,Chinese01_5,Chinese01_3,Chinese01_0,Chinese01_6','Chinese01_4,Chinese01_2,Chinese01_1,Chinese01_8,Chinese01_7','Chinese01_9,Chinese01_6,Chinese01_5,Chinese01_3,Chinese01_2','Chinese01_7,Chinese01_4,Chinese01_0,Chinese01_9,Chinese01_5'];
break;
case '10':
arrayCharacter = ['Arabic01_0,Arabic01_1,Arabic01_6,Arabic01_3,Arabic01_2','Arabic01_3,Arabic01_2,Arabic01_4,Arabic01_8,Arabic01_7','Arabic01_6,Arabic01_9,Arabic01_5,Arabic01_0,Arabic01_1','Arabic01_4,Arabic01_3,Arabic01_0,Arabic01_7,Arabic01_9','Arabic01_8,Arabic01_1,Arabic01_2,Arabic01_5,Arabic01_6','Arabic01_9,Arabic01_8,Arabic01_6,Arabic01_4,Arabic01_0','Arabic01_1,Arabic01_7,Arabic01_3,Arabic01_9,Arabic01_5','Arabic01_5,Arabic01_0,Arabic01_2,Arabic01_7,Arabic01_8','Arabic01_6,Arabic01_3,Arabic01_8,Arabic01_4,Arabic01_1','Arabic01_2,Arabic01_4,Arabic01_1,Arabic01_7,Arabic01_9','Arabic01_8,Arabic01_5,Arabic01_3,Arabic01_0,Arabic01_6','Arabic01_4,Arabic01_2,Arabic01_1,Arabic01_8,Arabic01_7','Arabic01_9,Arabic01_6,Arabic01_5,Arabic01_3,Arabic01_2','Arabic01_7,Arabic01_4,Arabic01_0,Arabic01_9,Arabic01_5'];
break;
case '11':
arrayCharacter = ['Hebrew01_2,Hebrew01_8,Hebrew01_0,Hebrew01_6,Hebrew01_4','Hebrew01_7,Hebrew01_1,Hebrew01_5,Hebrew01_9,Hebrew01_3','Hebrew01_8,Hebrew01_0,Hebrew01_2,Hebrew01_4,Hebrew01_6','Hebrew01_9,Hebrew01_5,Hebrew01_7,Hebrew01_3,Hebrew01_1','Hebrew01_6,Hebrew01_4,Hebrew01_8,Hebrew01_0,Hebrew01_2','Hebrew01_1,Hebrew01_3,Hebrew01_9,Hebrew01_5,Hebrew01_7','Hebrew01_0,Hebrew01_6,Hebrew01_4,Hebrew01_2,Hebrew01_8','Hebrew01_5,Hebrew01_7,Hebrew01_3,Hebrew01_1,Hebrew01_9','Hebrew01_4,Hebrew01_2,Hebrew01_8,Hebrew01_6,Hebrew01_0','Hebrew01_3,Hebrew01_9,Hebrew01_1,Hebrew01_7,Hebrew01_5','Hebrew01_2,Hebrew01_6,Hebrew01_0,Hebrew01_8,Hebrew01_4','Hebrew01_7,Hebrew01_5,Hebrew01_9,Hebrew01_1,Hebrew01_3','Hebrew01_8,Hebrew01_4,Hebrew01_2,Hebrew01_0,Hebrew01_6','Hebrew01_1,Hebrew01_5,Hebrew01_7,Hebrew01_3,Hebrew01_9'];
break;
/* case '12':
arrayCharacter = ['CrowdedHOTV01_0','CrowdedHOTV01_2','CrowdedHOTV01_3','CrowdedHOTV01_1','CrowdedHOTV01_2','CrowdedHOTV01_0','CrowdedHOTV01_1','CrowdedHOTV01_3','CrowdedHOTV01_1','CrowdedHOTV01_0','CrowdedHOTV01_2','CrowdedHOTV01_3','CrowdedHOTV01_0','CrowdedHOTV01_2'];
break;
case '13':
arrayCharacter = ['CrowdedHOTV01_0,CrowdedHOTV01_2','CrowdedHOTV01_2,CrowdedHOTV01_3','CrowdedHOTV01_3,CrowdedHOTV01_1','CrowdedHOTV01_1,CrowdedHOTV01_0,CrowdedHOTV01_2','CrowdedHOTV01_2,CrowdedHOTV01_3,CrowdedHOTV01_1','CrowdedHOTV01_0,CrowdedHOTV01_1,CrowdedHOTV01_3','CrowdedHOTV01_1,CrowdedHOTV01_2,CrowdedHOTV01_0','CrowdedHOTV01_3,CrowdedHOTV01_0,CrowdedHOTV01_2','CrowdedHOTV01_1,CrowdedHOTV01_2,CrowdedHOTV01_3','CrowdedHOTV01_0,CrowdedHOTV01_3,CrowdedHOTV01_1','CrowdedHOTV01_2,CrowdedHOTV01_1,CrowdedHOTV01_0','CrowdedHOTV01_3,CrowdedHOTV01_0,CrowdedHOTV01_2','CrowdedHOTV01_0,CrowdedHOTV01_3,CrowdedHOTV01_1','CrowdedHOTV01_2,CrowdedHOTV01_1,CrowdedHOTV01_3'];
break; */
}
//reverse the order of each line if config set to Mirrored
if(localsMirrored == 2) {
for(p=0;p<arrayCharacter.length;p++) {
var arSplit = arrayCharacter[p].split(',');
arSplit.reverse();
var arJoined = arSplit.join(',');
arrayCharacter[p]=arJoined;
}
}
//add indicator dots to lines 3 (6/6 or equiv) and 6 (6/12 or equiv)
arrayCharacter[3]="red_rect,"+arrayCharacter[3]+",red_rect";
arrayCharacter[6]="green_dot,"+arrayCharacter[6]+",green_dot";
var arrayHeight = -1, counter = 0;
for (var i = 0; i < arrayCharacter.length; i++) {
arrayHeight++;
var scoreText = chartArray[arrayHeight][1]; //get score text
var heightText = (localOptotype == 10) ? chartArray[arrayHeight][2]*9/5 : chartArray[arrayHeight][2]; //get height for character
var marginText = (localOptotype == 10) ? heightText : heightText / 2; //get height for character
var splitArr = arrayCharacter[i].split(',');
for (var x = 0; x < splitArr.length; x++) {
var alphabet = splitArr[x];
//set style and append svg
$('#list-character #' + alphabet).clone().css({
height: heightText + 'mm',
margin: heightText + 'mm ' + marginText + 'mm',
}).attr({
id: alphabet + '_'+counter,
}).appendTo('#line-' + (i + 1));
counter ++;
};
var attrWidth = 0;
$('#line-' + (i + 1)).find('svg').each(function () {
if ($(this).find('>:first-child').is('polygon')) {
attrWidth = $(this).find('>:first-child').width();
}
});
if (attrWidth != 0) {
$('#line-' + (i + 1)).find('svg').attr('width', attrWidth);
}
//set height for parent line
$('#line-' + (i + 1)).css('height', heightText + 'mm');
$('#line-' + (i + 1)).css('line-height', heightText + 'mm');
$('#line-' + (i + 1)).css('margin', heightText/2 + 'mm');
var parentHeight = convertFunction.ConvertPixelToMM($('#line-' + (i + 1)).parent().height() / 2 - 12.5);
var scoreBoxCol = colours.optotype.replace(/[\d\.]+\)$/g, '1');
$('<div class="scoreBox" >' + scoreText + '</div>').insertAfter('#line-' + (i + 1)).css({color:scoreBoxCol});
//calculator viewport width - here we check if 5 letters plus 2 margins will fit on screen and if not,
//chop off end letters and try again. If even one letter won't fit, don't display the line at all
var svgBox = $('#line-' + (i + 1)).find('svg:first-child').width(), //get widht of line
svgMargin = parseFloat($('#line-' + (i + 1)).find('svg:first-child').css('margin-left')) * 2;
var svgWidth = svgBox + svgMargin; //get width for each character
var firstChartRemove = $('#line-' + (i + 1)).find('svg:nth-child(1)'),
secondChartRemove = $('#line-' + (i + 1)).find('svg:nth-child(2)'),
thirdChartRemove = $('#line-' + (i + 1)).find('svg:nth-child(3)'),
fourthChartRemove = $('#line-' + (i + 1)).find('svg:nth-child(4)'),
fifthChartRemove = $('#line-' + (i + 1)).find('svg:nth-child(5)');
//allow for the scoreBox when fitting letters on lines
var lineWidth = viewWidth-60;//60 is the width of scoreBox set in style header
if (lineWidth >= svgWidth * 7) {
//console.log('show all');
$('#line-' + (i + 1)).find('svg').show();
}
else if (lineWidth >= svgWidth * 5) {
//console.log('5');
//remove dots
$('#line-' + (i + 1)).find('svg.guide-dot').remove();
$('#line-' + (i + 1)).find('svg').show();
}
else if (lineWidth >= svgWidth * 4) {
//console.log('4');
//remove dots
$('#line-' + (i + 1)).find('svg.guide-dot').remove();
$('#line-' + (i + 1)).find('svg').show();
thirdChartRemove.hide();
}
else if (lineWidth >= svgWidth * 3) {
//console.log('3');
$('#line-' + (i + 1)).find('svg.guide-dot').remove();
$('#line-' + (i + 1)).find('svg').show();
secondChartRemove.hide();
thirdChartRemove.hide();
}
else if (lineWidth >= svgWidth * 2) {
//console.log('2');
$('#line-' + (i + 1)).find('svg.guide-dot').remove();
$('#line-' + (i + 1)).find('svg').show();
secondChartRemove.hide();
thirdChartRemove.hide();
fourthChartRemove.hide();
}
else if (lineWidth >= svgWidth) {
//console.log('1');
$('#line-' + (i + 1)).find('svg.guide-dot').remove();
$('#line-' + (i + 1)).find('svg').show();
secondChartRemove.hide();
thirdChartRemove.hide();
fourthChartRemove.hide();
fifthChartRemove.hide();
}
else {
//console.log('0');
$('#line-' + (i + 1)).find('svg').hide();
$('#line-' + (i + 1)).parent().find('.scoreBox').hide();
$('#line-' + (i + 1)).parent().addClass('display-none');
}
};
};
this.GenerateSingleCharts = function () {
var callBackFunction = this;
//make all charts not class V 100% height
var otherChart = $('#otherChart');
otherChart.css({
'height':viewHeight,
'width':viewWidth,
});
//select svg of all the charts that aren't class V
var charts = $('.chart:not(.V)')
var chartsSVG = charts.find('svg');
//all single charts except animations are based on minimum element subtense equivalent to a 6/12 letter
//get subtense of 2 arcmin calculated already for the letter charts, converted to pixels
var elSubtense = callBackFunction.ConvertMMToPixel(chartArray[6][2]/5);
for (var s=0;s<chartsSVG.length;s++) {
var svg = chartsSVG[s];
//svg is centred with css text-align on the chart
var svgW = svg.viewBox.baseVal.width*elSubtense, svgH = svg.viewBox.baseVal.height*elSubtense,
svgX = viewWidth/2-svgW/2, svgY = viewHeight/2-svgH/2;
var strTrans = 'translate(0,'+svgY+'px)';
if(localsMirrored == 2) {
strTrans += 'scale(-1,1)';
}
var thisChart = $('#'+chartsSVG[s].id);
if(!thisChart.parent().hasClass('animated')) {//exclude animated charts which will be fullscreen
thisChart.attr({
'width':svgW,
}).css({
'transform':strTrans,//svg 1.0 doesn't allow transform on SVG, so only some browsers allow it
});
} else {
thisChart.attr({
'width': viewWidth,
'height': viewHeight*0.8,
}).css({
'transform': 'translate(0,'+viewHeight*0.1+'px)',//but does allow css transform
});
}
}
//update filter hues
$('.filterGreen').attr('fill','hsl('+colours.fGreenHue+',80%,60%)');
$('.filterRed').attr('fill','hsl('+colours.fRedHue+',80%,60%)');
//put a function on each single chart that can be mapped to spacebar
var singleCharts = $('.chart:not(.V)');
singleCharts.each(function (idx,el) {
var elem = $(el).find('svg');
if (elem.length>0){
$(el).off();
$(el).on('click',callBackFunction.spaceBarFunc);
}
});
};
this.spaceBarFunc = function (e) {
var callBackFunction = this;
var el = $(e.currentTarget).children('svg')[0];
var thisChart = objWolf[objWolf.catThis].arCharts[objWolf.chartThis];
switch (el.id) {
case 'rSeptumChart':
spaceSeptumChart(el);
break;
case 'bFixDisp':
rotate90(el);
swapSVGLayers($('.rotate-button'));
thisChart.isToggled = !thisChart.isToggled;
break;
case 'rJCCDots':
case 'rBullseye':
case 'bWorth4Dot':
case 'mWhiteDot':
swapSVGLayers(el);
swapSVGLayers($('.zoom-button'));
thisChart.isToggled = !thisChart.isToggled;
break;
default:
break;
}
function swapSVGLayers (el) {
var layers = $(el).children('g');
layers.each(function(idx,el) {
$(el).toggle();
});
}
function rotate90 (el) {
var angle = 90, trans = $(el).css('transform');
if(!thisChart.isToggled) {
trans +=' rotate(-'+angle+'deg)';
}
else {
trans +=' rotate('+angle+'deg)';
}
$(el).css('transform',trans);
}
function spaceSeptumChart () {
thisChart.isToggled = true;
var buttonLayers = $('.interspace-button').find('g');
$(buttonLayers[0]).hide();
$(buttonLayers[1]).show();
var scLGroup = $('#scLGroup'), scRGroup = $('#scRGroup');
var trans = [scRGroup.attr('transform'),scLGroup.attr('transform')], transX =[];
trans.forEach(function (el, idx) {
transX[idx] = getXTrans(el);
});
if (transX[0] == 22) {
transX=[15,-3];
thisChart.isToggled = false;
swapSVGLayers($('.interspace-button'));
}
scRGroup.attr('transform','translate('+(transX[0]+1)+',0)');
scLGroup.attr('transform','translate('+(transX[1]-1)+',0)');
function getXTrans (str) {
var temp=str.substring(
str.lastIndexOf("(") + 1,
str.lastIndexOf(",")
);
return parseInt(temp);
}
}
}
this.YatesShuffle = function (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
this.shuffleLetters = function () {
if(objWolf.catThis == 0) {
//check if letters are displayed in a column or singled
var colCheck = $('.in-a-column, .disable');
//if not, shuffle, else do nothing
if(colCheck.length == 0) {
var callBack = this;
callBack.swapSVGLayers($('.shuffle-button'));
if(!objWolf.isShuffled) {
$('.char-line').each(function (index) {
var parent = $(this);
var arVisible = parent.find('svg:not([style*="display: none"])'),
arDots = parent.find('svg.guide-dot');
//count how many letters are visible
var lineLength = arVisible.length;
//hide all the letters
arAlphabet = parent.find('svg.optotype-symbol').hide(),
//shuffle them
arAlphabet = callBack.YatesShuffle(arAlphabet);
//append shuffled letters to the number in the pre-shuffled line
for (i = 0; i < lineLength; i++) {
$(arAlphabet[i]).appendTo(parent).show();
}
if (arDots.length != 0) {
parent.prepend(arDots[0]).append(arDots[1]);
}
$('#sUnshuffled').attr('display','block');
$('#sShuffled').attr('display','none');
});
} else {
callBack.UnShuffleFunction(oldCharacter);
$('#sUnshuffled').attr('display','none');
$('#sShuffled').attr('display','block');
}
objWolf.isShuffled=!objWolf.isShuffled;
}
}
}
this.UnShuffleFunction = function (oldCharacter) {
for (i = 0; i < oldCharacter.length; i++) {
var id = oldCharacter[i][0],
svg = oldCharacter[i][1];
var dataLine = $('.chart.V').find('>div[data-line=' + id + ']').html(svg);
if (objWolf.isDuo) {
$('.guide-dot').hide();
}
}
};
this.duoBGFunction = function () {
var callBack = this;
//check if letters are displayed in a column, or singled
var colCheck = $('.in-a-column, .disable');
//only duochrome if not a column
if(colCheck.length == 0) {
if(objWolf.catThis == 0) {
$('#letterChart').toggleClass('duo');
$('.guide-dot').toggle();
objWolf.isDuo = !objWolf.isDuo;
callBack.swapSVGLayers($('.bg-button'));
}
}
};
this.swapSVGLayers = function (el) {
var layers = $(el).children('g');
layers.each(function(idx,el) {
$(el).toggle();
});
}
this.letterMorph = function () {
var callBack = this;
var arPolygons = $('#list-character .optotype-symbol[id^=Snellen_] polygon'), maxLen = 0, counter = 0;
var interval = arPolygons.length * 1350;
var hue=0;
//find the max length the polygon points array
for (var a = 0; a < arPolygons.length; a++) {
var len = arPolygons[a].points.length
if (len > maxLen) {
maxLen = len;
}
}
//make all the polygon points arrays the same length
for (var b = 0; b < arPolygons.length; b++) {
var len = maxLen - arPolygons[b].points.length, ar = [];
if (arPolygons[b].points.length < 12) {
for (var d = 0; d < len; d++) {
var dummyPt = document.getElementById("mLetterMorph").createSVGPoint({
x: 0,
y: 0,
})
arPolygons[b].points.appendItem(dummyPt);
}
}
}
//make animations between each polygon
var starter = setTimeout(() => {
newLetterMorph();
}, 1000);
var timer = setInterval(() => {
newLetterMorph();
}, (interval+1000));
var timer2 = setInterval(() => {
hue=Math.random()*360;
$('#SVGLetter').attr({
fill: 'hsl('+hue+',50%,50%)',
})
}, 450);
function newLetterMorph() {
arPolygons = YatesShuffle(arPolygons);
var newTarget = $('#mLetterMorph').clone();
newTarget.find('#SVGLetter :not(:first-child)').remove();
makeAnimations(newTarget.find('#SVGLetter'));
$('#mLetterMorph').replaceWith(newTarget);
}
function makeAnimations(targetPolygon) {
targetPolygon.find('#morph0').attr({
from: $(arPolygons[0]).attr('points'),
to: $(arPolygons[1]).attr('points'),
});
for (var e = 1; e < arPolygons.length; e++) {
var animId = "morph" + (e - 1);
targetPolygon.find('#morph0').clone().attr({
id: "morph" + e,
begin: animId + ".end +1s",
from: $(arPolygons[e]).attr('points'),
to: $(arPolygons[e + 1]).attr('points'),
}).appendTo(targetPolygon);
}
var lastAnim = $(targetPolygon).find(':last-child');
lastAnim.attr({
to: $(arPolygons[0]).attr('points'),
})
//console.log(targetPolygon);
}
function YatesShuffle (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!.attr('points')
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
}
this.ShortCutKey = function (pageUp, pageDown, pageLeft, pageRight, shuffle, duoBG) {
var callBack = this;
document.body.onkeyup = function (e) {
//disable shortcuts if setting bar is active
if(!$('#setting-bar').hasClass('active')) {
//exclude the ctrl key wherever a letter is the keycode, but not the arrows
if (pageUp != "") {
if (e.keyCode == pageUp && e.ctrlKey == false) {
callBack.scrollChart(objWolf.catThis,objWolf.chartU(),'top');
};
};
if (pageDown != "") {
if (e.keyCode == pageDown && e.ctrlKey == false) {
callBack.scrollChart(objWolf.catThis,objWolf.chartD(),'bottom');
};
};
if (pageLeft != "") {
if (e.keyCode == pageLeft && e.ctrlKey == false) {
callBack.navCat(objWolf.catLeft(),'left');
};
};
if (pageRight != "") {
if (e.keyCode == pageRight && e.ctrlKey == false) {
callBack.navCat(objWolf.catRight(),'right');
};
};
if (e.keyCode == 38) {
e.preventDefault();
callBack.scrollChart(objWolf.catThis,objWolf.chartU(),'top');
};
if (e.keyCode == 40) {
e.preventDefault();
callBack.scrollChart(objWolf.catThis,objWolf.chartD(),'bottom');
};
if (e.keyCode == 37) {
e.preventDefault();
callBack.navCat(objWolf.catLeft(),'left');
};
if (e.keyCode == 39) {
e.preventDefault();
callBack.navCat(objWolf.catRight(),'right');
};
if (e.keyCode == 86 && e.ctrlKey == false) {
e.preventDefault();
callBack.navCat(0,'fav');
};
if (e.keyCode == 82 && e.ctrlKey == false) {
e.preventDefault();
callBack.navCat(1,'fav');
};
if (e.keyCode == 66 && e.ctrlKey == false) {
e.preventDefault();
callBack.navCat(2,'fav');
};
if (e.keyCode == 77 && e.ctrlKey == false) {
e.preventDefault();
callBack.navCat(3,'fav');
};
if (e.key === ' ' || e.key === 'Spacebar') {
e.preventDefault();
$("#"+objWolf.chartThisId).trigger('click');
}
if (shuffle != "") {
if (e.keyCode == shuffle && e.ctrlKey == false) {
e.preventDefault();
callBack.shuffleLetters();
}
};
if (duoBG != "") {
if (e.keyCode == duoBG && e.ctrlKey == false) {
e.preventDefault();
callBack.duoBGFunction();
};
};
}
};//end of onkeyup
};
this.ValidateFunction = function () {
var result = false,
resultDistance, resultLength;
var validateFunction = this;
$('#iDistance').on('change', function () {
resultDistance = validateFunction.ValidateDistance();
});
$('#iLengOfLine').on('change', function () {
resultLength = validateFunction.ValidateLengOfLine();
});
if (resultDistance || resultLength) {
result = true;
}
return result;
};
this.ValidateDistance = function () {
var result = false,
message = "",
distance = $('#iDistance').val();
$('.errorDistance').remove();
if (distance == "") {
result = true;
message = "Distance is required.";
}
else if (distance != parseInt(distance, 10)) {
result = true;
message = "Distance must be integer.";
}
else if (distance < 3000) {
result = true;
message = "Distance must be greater than or equal to 3000.";
}
if (result) {
$('#iDistance').parent().append('<span class="errorMsg errorDistance">' + message + '</span>');
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
}
return result;
};
this.ValidateLengOfLine = function () {
var result = false,
message = "",
lengOfLine = $('#iLengOfLine').val();
$('.errorLenghtLine').remove();
if (lengOfLine == "") {
result = true;
message = "Length of line below is required.";
}
else if (isNaN(lengOfLine)) {
result = true;
message = "Length of line below must be numbered.";
}
else if (parseFloat(lengOfLine) < 25 || parseFloat(lengOfLine) > 250) {
result = true;
message = "The length of line must be between 25 and 250.";
}
if (result) {
$('#iLengOfLine').parent().append('<span class="errorMsg errorLenghtLine">' + message + '</span>');
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
}
return result;
};
this.ValidateDuplicateKey = function (element) {
$('.errorShortKey').remove();
var arr = $('.js-shortkey').map(function () {
return this.value; // $(this).val()
}).get();
//reserve the shortcut keys for chart categories
arr = [...arr,'v','r','b','m'];
function countInArray(array, what) {
return array.filter(item => item == what).length;
}
var result = false;
var currentVal = $(element).val();
if (currentVal.trim() != "") {
if (countInArray(arr, currentVal) > 1) {
result = true;
}
}
if (result) {
$(element).parent().append('<span class="errorMsg errorShortKey">ShortKey ' + currentVal + ' is duplicate, or is reserved for another function. Please try again.</span>');
$(element).val("");
}
else {
$(element).parent().find('.errorShortKey').remove();
}
return result;
};
this.SetLocalStorage = function () {
localStorage.setItem("Ver", ver);
localStorage.setItem("Optotype", localOptotype);
localStorage.setItem("Alphabet", alphabetType);
localStorage.setItem("Notation", notation);
localStorage.setItem("Numerator", numeratorType);
localStorage.setItem("Distance", localDistance);
localStorage.setItem("LengthOfLine", lenghOfline);
localStorage.setItem("DisplayOptions", displayOrder);
localStorage.setItem("DisplayWidth", viewWidth);
localStorage.setItem("Mirrored", localsMirrored);
localStorage.setItem("Colours", JSON.stringify(colours));
localStorage.setItem("ObjWolf", JSON.stringify(objWolf));
localStorage.setItem("Shortcuts", JSON.stringify(shortcuts));
};
this.SetScoreBoxFont = function () {
//reduce font size of scoreBox from that set in css
//if Notation is Feet, or is Metres and Numerator is Actual
//other Notations have no numerator so are max 4 chars
if(notation==2 || (notation==1 && numeratorType==1)) {
$('.scoreBox').css({
'font-size': '4mm',
});
}
}
//reverse the characters for mirrored display. The order of characters is also reversed at the point where
//the lines are built from the arrayCharacter variable above
this.SetDirectCharacter = function (localsMirrored) {
if (localsMirrored == "2") {
$('#letterChart svg').css('transform', 'rotateY(180deg)');
}
else {
$('#letterChart svg').css('transform', 'rotateY(0deg)');
}
};
this.ResetValueToDefault = function () {
var setConfigDefault = this;
$('#reset').on('click', function () {
setConfigDefault.SetConfigDefault();
//set variable for local storage
notation = $('#sNotation').val(),
localOptotype = $('#type').val(),
localsMirrored = $('#sMirrored').val(),
localDistance = $('#iDistance').val().trim(),
numeratorType = $('#sNumerator').val(),
alphabetType = $('#sAlphabet').val(),
shortcuts[0] = $('#pageUp').val().trim(),
shortcuts[1] = $('#pageDown').val().trim(),
shortcuts[2] = $('#pageLeft').val().trim(),
shortcuts[3] = $('#pageRight').val().trim(),
shortcuts[4] = $('#shuffle').val().trim(),
shortcuts[5] = $('#duoBG').val().trim(),
lenghOfline = $('#iLengOfLine').val().trim(),
displayOrder = $('#display').val(),
setConfigDefault.SetLocalStorage();
$('#letterChart > div').find('.char-line').html('');
$('#letterChart > div').find('.scoreBox').remove();
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
setConfigDefault.removeLetterChartPage();
$('.char-line').removeAttr('style');
configBar.init();
});
};
this.GetConfigByValue = function () {
var gOptotype = localStorage.getItem("Optotype"),
gAlphabet = localStorage.getItem("Alphabet"),
gNotation = localStorage.getItem("Notation"),
gNumerator = localStorage.getItem("Numerator"),
gDistance = localStorage.getItem("Distance"),
gLengthOfLine = localStorage.getItem("LengthOfLine"),
gDisplayOptions = localStorage.getItem("DisplayOptions"),
gDisplayWidth = localStorage.getItem("DisplayWidth"),
gDisplayHeight = localStorage.getItem("DisplayHeight"),
gMirrored = localStorage.getItem("Mirrored");
gColours = JSON.parse(localStorage.getItem("Colours")),
objWolf = JSON.parse(localStorage.getItem("ObjWolf")),
gShortcuts = JSON.parse(localStorage.getItem("Shortcuts"));
//set value for input
$('#sOptotype').val(gOptotype).change();
$('#sAlphabet').val(gAlphabet);
$('#sNotation').val(gNotation);
$('#sNumerator').val(gNumerator);
$('#iDistance').val(gDistance);
$('#iLengOfLine').val(gLengthOfLine);
$('#display').val(gDisplayOptions);
$('#sMirrored').val(gMirrored);
$('#tOptoColour').val(gColours.optotype);
$('#tBgColour').val(gColours.backgrounds.optotype);
$('#sliderRed').val(gColours.fRedHue);
$('#sliderGreen').val(gColours.fGreenHue);
$('#pageUp').val(gShortcuts[0]);
$('#pageDown').val(gShortcuts[1]);
$('#pageLeft').val(gShortcuts[2]);
$('#pageRight').val(gShortcuts[3]);
$('#shuffle').val(gShortcuts[4]);
$('#duoBG').val(gShortcuts[5]);
};
this.SetConfigDefault = function () {
//set value for input
$('#sOptotype').val("1").change();
$('#sAlphabet').val("2");
$('#sNotation').val("1");
$('#sNumerator').val("2");
$('#display').val('1');
$('#sMirrored').val('2');
colours = {
optotype: 'rgba(0,0,0,1)',
backgrounds: {
optotype: 'rgba(255,255,255,1)',
binocular: 'hsl(0,0%,60%)',
},
fRedHue: '360',
fGreenHue: '160',
themes: {
R: 'rgb(174,39,96)',
B: 'rgb(154,204,154)',
M: 'rgb(214, 116, 10)',
},
}
$('#tOptoColour').val(colours.optotype).siblings('i').css('background-color',colours.optotype);
$('#tBgColour').val(colours.backgrounds.optotype).siblings('i').css('background-color',colours.backgrounds.optotype);
$('#sliderRed').val(colours.fRedHue).css('background','hsl('+colours.fRedHue+',80%,60%)');
$('#sliderGreen').val(colours.fGreenHue).css('background','hsl('+colours.fGreenHue+',80%,60%)');
$('#iDistance').val('');
$('#iLengOfLine').val('');
shortcuts = ['u','n','g','k','q','z'];
$('#pageUp').val(shortcuts[0]);
$('#pageDown').val(shortcuts[1]);
$('#pageLeft').val(shortcuts[2]);
$('#pageRight').val(shortcuts[3]);
$('#shuffle').val(shortcuts[4]);
$('#duoBG').val(shortcuts[5]);
};
this.UpdateVersion = function (version) {
//console.log(version+", "+colours+", "+shortcuts);
var majVer = Math.floor(version), minVer = (version-majVer)*10;
//create new storage items
localStorage.setItem("Ver",JSON.stringify(version));
//convert old storage items
var reserved = ['v','r','b','m'],oldShortcuts=[],banned="",errMess="";
oldShortcuts[0] = localStorage.getItem("PageUp");
oldShortcuts[1] = localStorage.getItem("PageDown");
oldShortcuts[4] = localStorage.getItem("Shuffle");
oldShortcuts[5] = localStorage.getItem("duoBG");
oldShortcuts.forEach(function (val,idx) {
if(reserved.includes(val)) {
shortcuts[idx]="";
errMess = "Warning:\nOne or more of your keyboard shortcuts will no longer work, as it is now reserved for something else. Please assign new shortcut(s) at the bottom of the config menu";
} else {
shortcuts[idx] = val;
}
});
colours.optotype = localStorage.getItem("TextColor");
colours.backgrounds.optotype = localStorage.getItem("BgColor");
localStorage.setItem("Colours",JSON.stringify(colours));
localStorage.setItem("Shortcuts",JSON.stringify(shortcuts));
//destroy no longer needed items
localStorage.removeItem("PageUp");
localStorage.removeItem("PageDown");
localStorage.removeItem("Shuffle");
localStorage.removeItem("Unshuffle");
localStorage.removeItem("duoBG");
localStorage.removeItem("TextColor");
localStorage.removeItem("BgColor");
//alert
var alertMess = "You have updated to WolfChart "+majVer+". Please take a moment to review your settings."
if(errMess!="") {
alert (alertMess+"\n"+errMess);
} else {
alert (alertMess);
}
}
this.ConvertPixelToMM = function (pixel) {
var dpi = document.getElementById("dpi").offsetHeight;
return (pixel * 25.4) / dpi
};
this.ConvertMMToPixel = function (mm) {
var dpi = document.getElementById("dpi").offsetHeight;
return (mm * dpi) / 25.4
};
this.removeLetterChartPage = function () {
var $scrollDiv = $('#letterChart').find('.V');
if ($scrollDiv.length > 0) {
$scrollDiv.each(function () {
$(this).find('>div').detach().appendTo('#letterChart');
});
};
$('.V').remove();
};
this.PageLetterChart = function () {
//#letterChart has been filled with lines of letters from smallest to largest but they are not in pages
//maintain this order
if(objWolf.chartThis){objWolf.chartThis = null};
var firstLine = parseInt($('#letterChart > div:nth-child(1)').attr('data-line')),
secondLine = parseInt($('#letterChart > div:nth-child(2)').attr('data-line'));
if (firstLine > secondLine) {
$('#letterChart > div').each(function () {
$(this).detach().prependTo($('#letterChart'))
});
}
//most efficient to page the letter chart now, then rearrange for Option Sort
var quotalHeight = 0, pageCounter = 0;
$('#letterChart >div').each(function () {
if ($(this).find('.char-line').height() > 0) {
if ($(this).height() + quotalHeight <= viewHeight) {
quotalHeight = quotalHeight + $(this).height();
}
else {
quotalHeight = $(this).height();
$('<div class="chart V" id="V'+pageCounter+'"></div>').css('display','none').appendTo('#letterChart');
$(this).prevAll().each(function () {
$(this).detach().prependTo($('#letterChart').find('.V:last'));
});
pageCounter ++;
}
}
});
if ($('#letterChart >div').not(".V").length > 0) {
$('<div class="chart V"></div>').attr('id',"V"+pageCounter).css('display','none').appendTo('#letterChart');
$('#letterChart >div').not(".V").each(function () {
if ($(this).find('.char-line svg').length > 0) {
$(this).detach().prependTo($('#letterChart').find('.V:last'));
}
else {
$(this).detach().appendTo('#letterChart');
}
})
}
$('.V').each(function () {
if ($(this).find('>div').hasClass('display-none')) {
$(this).remove();
}
});
//---Display Order-----
//Largest at top of each page. First page is handled when scrollChart() is called
if (displayOrder == "1" || displayOrder == "2") {
//just need to reverse order of lines on each page
$('.V').each(function () {
var chart = $(this), children = chart.children();
chart.append(children.get().reverse());
});
} else {//Monoyer means smallest at top of each page, and page of smallest lines is highest numbered page
$('#letterChart').each(function () {
//just need to reverse order of pages
var letterCharts = $(this), children = letterCharts.children();
letterCharts.append(children.get().reverse());
});
}
}
this.loadCharts = function () {
functionConfigWolfChart = this;
var allCharts = $('.chart'), arTemp = [], counter = 0;
//quick and dirty way to make unique categories
allCharts.each(function (idx, el) {
var category = el.id.substr(0, 1);
arTemp[category] = 0;
});
//populate objWolf with numbered chart categories
//each with all the charts of that class,
//each chart with initial use count of 0
//and some other useful properties
for (var key in arTemp) {
if (arTemp.hasOwnProperty(key)) {
objWolf[counter] = {cat:key,title:"",col:"",lastUsed:0,mostUsed:0,arCharts:[]};
counter ++;
objWolf.catsLength ++;
}
}
//add properties for each category
var themeColours = colours.themes;
//console.log(objWolf);
for (q = 0; q < objWolf.catsLength; q++) {
var thing = objWolf[q];
//console.log(thing);
thing.col = "rgb(127,127,127)";
if (thing.cat == "V") {
thing.title = "VA";
thing.col = "rgb(0,0,0)";
}
switch (thing.cat) {
case 'R':
thing.title = "Refraction";
thing.col = themeColours.R;
break;
case 'B':
thing.title = "Binocular";
thing.col = themeColours.B;
break;
case 'M':
thing.title = "Misc.";
thing.col = themeColours.M;
}
//add charts to each category in objWolf
var catCharts = $('.' + thing.cat);
catCharts.each(function (idx, el) {
thing.arCharts[idx] = {id:el.id,useCount:0,isToggled:false};
})
}
}
this.characterClick = function () {
$(document).on('click', '.optotype-symbol', function () {
var characterSVG = $('.char-line .optotype-symbol'), el = $(this),
guideDotSVG = $('svg.guide-dot');
if(el.hasClass('in-a-column')) {
//show all letters
characterSVG.attr('class','optotype-symbol');
if (!objWolf.isDuo) {
guideDotSVG.show();
}
}
else if (el.hasClass('active')) {
//show a column of letters containing this one
el.removeClass('active');
guideDotSVG.hide();
var lines = $('.char-line').each(function (idx, elem) {
var b = objWolf.pointer;
$(elem).find('.optotype-symbol').each(function (idx, elem) {
if (idx == b) {
$(elem).addClass('in-a-column');
$(elem).removeClass('disable');
}
});
});
}
else {
//show only the letter clicked
el.addClass('active');
characterSVG.addClass('disable');
el.removeClass('disable');
guideDotSVG.hide();
//find the position of the clicked letter along the line
var parent = this.parentNode, callBack = this, pos="";
$('#'+parent.id).find('.optotype-symbol').each(function (idx, elem) {
if (elem.id == callBack.id) {
objWolf.pointer = idx;
}
});
}
});
};
this.scoreBoxClick = function () {
$(document).on('click','.scoreBox, .guide-dot', function() {
var clicked = $(this), lineSVG = "", characterLine = $('.character-line .char-line'),
characterSVG = $('.char-line .optotype-symbol');
if(clicked[0].getAttribute('class')=="scoreBox") {
lineSVG = $(this).prev();
} else {
lineSVG = clicked.parent();
}
var activeElems = lineSVG.parent().find('.guide-dot, .scoreBox')
if(clicked.hasClass('active')) {
activeElems.removeClass('active');
characterLine.css('visibility','visible')
characterSVG.removeClass('disable active');
} else {
$('.character-line .scoreBox, .guide-dot').removeClass('active');
activeElems.addClass('active');
characterLine.css('visibility','hidden')
lineSVG.css('visibility','visible');
characterSVG.removeClass('disable active')
}
});
};
this.hideIdleMouse = function () {
var idleMouseTimer;
var forceMouseHide = false;
$("body").css('cursor', 'none');
$("#letterChart, #otherChart").mousemove(function (ev) {
if (!forceMouseHide) {
$("body").css('cursor', '');
clearTimeout(idleMouseTimer);
idleMouseTimer = setTimeout(function () {
$("body").css('cursor', 'none');
forceMouseHide = true;
setTimeout(function () {
forceMouseHide = false;
}, 200);
}, 5000);
}
});
};
this.swipeDetect = function (el, callback) {
var touchsurface = el,
swipedir,
startX,
startY,
distX,
distY,
threshold = 150, //required min distance traveled to be considered swipe
restraint = 100, // maximum distance allowed at the same time in perpendicular direction
allowedTime = 300, // maximum time allowed to travel that distance
elapsedTime,
startTime,
handleswipe = callback || function (swipedir) { }
touchsurface.addEventListener('touchstart', function (e) {
var touchobj = e.changedTouches[0]
swipedir = 'none'
dist = 0
startX = touchobj.pageX
startY = touchobj.pageY
startTime = new Date().getTime() // record time when finger first makes contact with surface
e.preventDefault()
}, false)
touchsurface.addEventListener('touchmove', function (e) {
e.preventDefault() // prevent scrolling when inside DIV
}, false)
touchsurface.addEventListener('touchend', function (e) {
var touchobj = e.changedTouches[0]
distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
elapsedTime = new Date().getTime() - startTime // get time elapsed
if (elapsedTime <= allowedTime) { // first condition for awipe met
if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint) { // 2nd condition for horizontal swipe met
swipedir = (distX < 0) ? 'left' : 'right' // if dist traveled is negative, it indicates left swipe
}
else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint) { // 2nd condition for vertical swipe met
swipedir = (distY < 0) ? 'up' : 'down' // if dist traveled is negative, it indicates up swipe
}
}
handleswipe(swipedir)
e.preventDefault()
}, false)
}
this.UpdateSetting = function () {
var callBackFunction = this, sideBarWidth = parseFloat($('#side-bar').css('width'));
$('#updateSetting').on('click', function () {
//set var from user input
notation = $('#sNotation').val(),
localOptotype = $('#sOptotype').val(),
localsMirrored = $('#sMirrored').val(),
localDistance = $('#iDistance').val().trim(),
viewWidth = window.innerWidth-sideBarWidth,
numeratorType = $('#sNumerator').val(),
colours.optotype = $('#tOptoColour').val().trim(),
colours.backgrounds.optotype = $('#tBgColour').val().trim(),
colours.fRedHue = $('#sliderRed').val(),
colours.fGreenHue = $('#sliderGreen').val(),
alphabetType = $('#sAlphabet').val(),
shortcuts[0] = $('#pageUp').val().trim(),
shortcuts[1] = $('#pageDown').val().trim(),
shortcuts[2] = $('#pageLeft').val().trim(),
shortcuts[3] = $('#pageRight').val().trim(),
shortcuts[4] = $('#shuffle').val().trim(),
shortcuts[5] = $('#duoBG').val().trim();
lenghOfline = $('#iLengOfLine').val().trim(),
displayOrder = $('#display').val(),
//reset div
$('#letterChart').html('<div data-line="1" class="character-line"><div class="char-line" id="line-1"></div></div><div data-line="2" class="character-line"><div class="char-line" id="line-2"></div></div>'
+ '<div data-line="3" class="character-line"><div class="char-line" id="line-3"></div></div><div data-line="4" class="character-line"><div class="char-line" id="line-4"></div></div>'
+ '<div data-line="5" class="character-line"><div class="char-line" id="line-5"></div></div><div data-line="6" class="character-line"><div class="char-line" id="line-6"></div></div>'
+ '<div data-line="7" class="character-line"><div class="char-line" id="line-7"></div></div><div data-line="8" class="character-line"><div class="char-line" id="line-8"></div></div>'
+ '<div data-line="9" class="character-line"><div class="char-line" id="line-9"></div></div><div data-line="10" class="character-line"><div class="char-line" id="line-10"></div></div>'
+ '<div data-line="11" class="character-line"><div class="char-line" id="line-11"></div></div><div data-line="12" class="character-line"><div class="char-line" id="line-12"></div></div>'
+ '<div data-line="13" class="character-line"><div class="char-line" id="line-13"></div></div><div data-line="14" class="character-line"><div class="char-line" id="line-14"></div></div>');
callBackFunction.removeLetterChartPage();
//validate required field
var validate = callBackFunction.ValidateFunction();
if (validate) {
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
return;
}
else {
//reset body div
$('body,#letterChart').removeAttr('style');
//reset letter chart
$('#letterChart > div >div').html('');
$('#letterChart .scoreBox').remove();
//hide all charts
$('.chart').hide();
//empty nav div
$('.nav-link').remove();
//create objWolf live operating object
callBackFunction.UpdateObjWolf();
//set text color
callBackFunction.SetColorCharacter(colours.optotype);
callBackFunction.SetBgColor(colours.backgrounds.optotype);
callBackFunction.CaculatorCharacterHeight(numeratorType);
//generate letter charts
callBackFunction.GenerateCharacter(alphabetType, localOptotype);
//generate single charts
callBackFunction.GenerateSingleCharts();
//set shortcut
callBackFunction.ShortCutKey(shortcuts[0].toUpperCase().charCodeAt(0),shortcuts[1].toUpperCase().charCodeAt(0),shortcuts[2].toUpperCase().charCodeAt(0),shortcuts[3].toUpperCase().charCodeAt(0),shortcuts[4].toUpperCase().charCodeAt(0),shortcuts[5].toUpperCase().charCodeAt(0));
//close setting bar
$('.setting-bar').removeClass('active');
$('.guide-section').removeClass('active');
$('.mask').removeClass('active');
var $Element, maxEleWidht = 0
$('#letterChart').css({'width':viewWidth,'height':viewHeight});
//set direct for character
callBackFunction.SetDirectCharacter(localsMirrored);
//set smaller font for long scoreBox strings
callBackFunction.SetScoreBoxFont();
//divide letter chart into pages
callBackFunction.PageLetterChart();
//load all charts into objWolf
callBackFunction.loadCharts();
//local storage
callBackFunction.SetLocalStorage();
//display a chart in the V category
callBackFunction.navCat(0,null);
//display nav bar
callBackFunction.DisplayNavigations();
callBackFunction.Clock();
//set old character array for the unshuffle function
$('.character-line').each(function () {
var lineArray = [];
lineArray.push($(this).attr('data-line'), $(this).html());
oldCharacter.push(lineArray);
});
$('.modal-setting').remove();
}
});
};
this.Init = function () {
var validateElement = this;
var validate = false,
VresultDistance, VresultLength;
$('#iDistance').on('blur', function () {
VresultDistance = validateElement.ValidateDistance();
if (VresultDistance || VresultLength) {
validate = true;
} else {
validate = false;
};
if (validate) {
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
$('.setting-button').trigger('click');
return;
}
else {
$('#updateSetting').removeClass('disabled-btn');
}
});
$('#iLengOfLine').on('blur', function () {
VresultLength = validateElement.ValidateLengOfLine();
if (VresultDistance || VresultLength) {
validate = true;
} else {
validate = false;
};
if (validate) {
$('#updateSetting').removeClass('disabled-btn').addClass('disabled-btn');
$('.setting-button').trigger('click');
return;
}
else {
$('#updateSetting').removeClass('disabled-btn');
}
});
$('.js-shortkey').on('blur', function () {
validateElement.ValidateDuplicateKey(this);
});
this.SelectOptotype();
this.DisplayArrows();
this.UpdateSetting();
if (localStorage.getItem("Optotype") != null) {
//following if deals with upgrade from v1 to v2.
//From ver 2.x, can use localStorage "Ver" string for this
if (localStorage.getItem("Ver") === null) {
this.UpdateVersion(ver);
this.GetConfigByValue();
$('.setting-button').trigger('click');
$('#updateSetting').removeClass('disabled-btn');
}
else if (localStorage.getItem("Distance") != "" && localStorage.getItem("LengthOfLine") != "") {
this.GetConfigByValue();
$('#updateSetting').trigger('click');
$('#updateSetting').removeClass('disabled-btn');
}
else {
$('.setting-button').trigger('click');
}
}
else if ($('#iDistance').val().trim() == "" || $('#iLengOfLine').val().trim() == "") {
$('.setting-button').trigger('click');
};
this.ResetValueToDefault();
this.characterClick();
this.scoreBoxClick();
this.hideIdleMouse();
/* this.swipeDetect(document.getElementById('letterChart'),function(swipedir) {
console.log("Swiped "+swipedir);
}); */
};
};
var configBar = new configBarSetting();
var configWolf = new ConfigWolfChart();
$(document).ready(function () {
configBar.init();
configWolf.Init();
});
</script>
</body>
</html>