diff --git a/Bench4Q-Web/src/main/webapp/agentManage.jsp b/Bench4Q-Web/src/main/webapp/agentManage.jsp index ec24f068..52e03c81 100644 --- a/Bench4Q-Web/src/main/webapp/agentManage.jsp +++ b/Bench4Q-Web/src/main/webapp/agentManage.jsp @@ -5,14 +5,20 @@ <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> Agent manage - + - - - - - - + + + + + + + @@ -36,14 +42,12 @@
- - + - +
@@ -131,14 +135,15 @@
- + - + diff --git a/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.css b/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.css deleted file mode 100644 index 299f46f0..00000000 --- a/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.css +++ /dev/null @@ -1,817 +0,0 @@ -/*! - * Bootstrap Responsive v2.0.4 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -.clearfix { - *zoom: 1; -} - -.clearfix:before, -.clearfix:after { - display: table; - content: ""; -} - -.clearfix:after { - clear: both; -} - -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.input-block-level { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; -} - -.hidden { - display: none; - visibility: hidden; -} - -.visible-phone { - display: none !important; -} - -.visible-tablet { - display: none !important; -} - -.hidden-desktop { - display: none !important; -} - -@media (max-width: 767px) { - .visible-phone { - display: inherit !important; - } - .hidden-phone { - display: none !important; - } - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } -} - -@media (min-width: 768px) and (max-width: 979px) { - .visible-tablet { - display: inherit !important; - } - .hidden-tablet { - display: none !important; - } - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important ; - } -} - -@media (max-width: 480px) { - .nav-collapse { - -webkit-transform: translate3d(0, 0, 0); - } - .page-header h1 small { - display: block; - line-height: 18px; - } - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - .form-horizontal .control-group > label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - .form-horizontal .controls { - margin-left: 0; - } - .form-horizontal .control-list { - padding-top: 0; - } - .form-horizontal .form-actions { - padding-right: 10px; - padding-left: 10px; - } - .modal { - position: absolute; - top: 10px; - right: 10px; - left: 10px; - width: auto; - margin: 0; - } - .modal.fade.in { - top: auto; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - .carousel-caption { - position: static; - } -} - -@media (max-width: 767px) { - body { - padding-right: 20px; - padding-left: 20px; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - margin-right: -20px; - margin-left: -20px; - } - .container-fluid { - padding: 0; - } - .dl-horizontal dt { - float: none; - width: auto; - clear: none; - text-align: left; - } - .dl-horizontal dd { - margin-left: 0; - } - .container { - width: auto; - } - .row-fluid { - width: 100%; - } - .row, - .thumbnails { - margin-left: 0; - } - [class*="span"], - .row-fluid [class*="span"] { - display: block; - float: none; - width: auto; - margin-left: 0; - } - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; - width: auto; - } -} - -@media (min-width: 768px) and (max-width: 979px) { - .row { - margin-left: -20px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - margin-left: 20px; - } - .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 724px; - } - .span12 { - width: 724px; - } - .span11 { - width: 662px; - } - .span10 { - width: 600px; - } - .span9 { - width: 538px; - } - .span8 { - width: 476px; - } - .span7 { - width: 414px; - } - .span6 { - width: 352px; - } - .span5 { - width: 290px; - } - .span4 { - width: 228px; - } - .span3 { - width: 166px; - } - .span2 { - width: 104px; - } - .span1 { - width: 42px; - } - .offset12 { - margin-left: 764px; - } - .offset11 { - margin-left: 702px; - } - .offset10 { - margin-left: 640px; - } - .offset9 { - margin-left: 578px; - } - .offset8 { - margin-left: 516px; - } - .offset7 { - margin-left: 454px; - } - .offset6 { - margin-left: 392px; - } - .offset5 { - margin-left: 330px; - } - .offset4 { - margin-left: 268px; - } - .offset3 { - margin-left: 206px; - } - .offset2 { - margin-left: 144px; - } - .offset1 { - margin-left: 82px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 28px; - margin-left: 2.762430939%; - *margin-left: 2.709239449638298%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .span12 { - width: 99.999999993%; - *width: 99.9468085036383%; - } - .row-fluid .span11 { - width: 91.436464082%; - *width: 91.38327259263829%; - } - .row-fluid .span10 { - width: 82.87292817100001%; - *width: 82.8197366816383%; - } - .row-fluid .span9 { - width: 74.30939226%; - *width: 74.25620077063829%; - } - .row-fluid .span8 { - width: 65.74585634900001%; - *width: 65.6926648596383%; - } - .row-fluid .span7 { - width: 57.182320438000005%; - *width: 57.129128948638304%; - } - .row-fluid .span6 { - width: 48.618784527%; - *width: 48.5655930376383%; - } - .row-fluid .span5 { - width: 40.055248616%; - *width: 40.0020571266383%; - } - .row-fluid .span4 { - width: 31.491712705%; - *width: 31.4385212156383%; - } - .row-fluid .span3 { - width: 22.928176794%; - *width: 22.874985304638297%; - } - .row-fluid .span2 { - width: 14.364640883%; - *width: 14.311449393638298%; - - } - .row-fluid .span1 { - width: 5.801104972%; - *width: 5.747913482638298%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 714px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 652px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 590px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 528px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 466px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 404px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 342px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 280px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 218px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 156px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 94px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 32px; - } -} - -@media (min-width: 1200px) { - .row { - margin-left: -30px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - margin-left: 30px; - } - .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 1170px; - } - .span12 { - width: 1170px; - } - .span11 { - width: 1070px; - } - .span10 { - width: 970px; - } - .span9 { - width: 870px; - } - .span8 { - width: 770px; - } - .span7 { - width: 670px; - } - .span6 { - width: 570px; - } - .span5 { - width: 470px; - } - .span4 { - width: 370px; - } - .span3 { - width: 270px; - } - .span2 { - width: 170px; - } - .span1 { - width: 70px; - } - .offset12 { - margin-left: 1230px; - } - .offset11 { - margin-left: 1130px; - } - .offset10 { - margin-left: 1030px; - } - .offset9 { - margin-left: 930px; - } - .offset8 { - margin-left: 830px; - } - .offset7 { - margin-left: 730px; - } - .offset6 { - margin-left: 630px; - } - .offset5 { - margin-left: 530px; - } - .offset4 { - margin-left: 430px; - } - .offset3 { - margin-left: 330px; - } - .offset2 { - margin-left: 230px; - } - .offset1 { - margin-left: 130px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 28px; - margin-left: 2.564102564%; - *margin-left: 2.510911074638298%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; - } - .row-fluid .span11 { - width: 91.45299145300001%; - *width: 91.3997999636383%; - } - .row-fluid .span10 { - width: 82.905982906%; - *width: 82.8527914166383%; - } - .row-fluid .span9 { - width: 74.358974359%; - *width: 74.30578286963829%; - } - .row-fluid .span8 { - width: 65.81196581200001%; - *width: 65.7587743226383%; - } - .row-fluid .span7 { - width: 57.264957265%; - *width: 57.2117657756383%; - } - .row-fluid .span6 { - width: 48.717948718%; - *width: 48.6647572286383%; - } - .row-fluid .span5 { - width: 40.170940171000005%; - *width: 40.117748681638304%; - } - .row-fluid .span4 { - width: 31.623931624%; - *width: 31.5707401346383%; - } - .row-fluid .span3 { - width: 23.076923077%; - *width: 23.0237315876383%; - } - .row-fluid .span2 { - width: 14.529914530000001%; - *width: 14.4767230406383%; - height:100%; - } - .row-fluid .span1 { - width: 5.982905983%; - *width: 5.929714493638298%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 1160px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 1060px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 960px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 860px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 760px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 660px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 560px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 460px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 360px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 260px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 160px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 60px; - } - .thumbnails { - margin-left: -30px; - } - .thumbnails > li { - margin-left: 30px; - } - .row-fluid .thumbnails { - margin-left: 0; - } -} - -@media (max-width: 767px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 18px; - } - .navbar-fixed-bottom { - margin-top: 18px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-right: 10px; - padding-left: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 9px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #999999; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 6px 15px; - font-weight: bold; - color: #999999; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .dropdown-menu a:hover { - background-color: #222222; - } - .nav-collapse.in .btn-group { - padding: 0; - margin-top: 5px; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - display: block; - float: none; - max-width: none; - padding: 0; - margin: 0 15px; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 9px 15px; - margin: 9px 0; - border-top: 1px solid #222222; - border-bottom: 1px solid #222222; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - height: 0; - overflow: hidden; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-right: 10px; - padding-left: 10px; - } -} - -@media (min-width: 768px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} diff --git a/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.min.css b/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.min.css deleted file mode 100644 index 09e88828..00000000 --- a/Bench4Q-Web/src/main/webapp/css/bootstrap-responsive.min.css +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Bootstrap Responsive v2.0.4 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ -.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}@media(max-width:767px){.visible-phone{display:inherit!important}.hidden-phone{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(min-width:768px) and (max-width:979px){.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{position:absolute;top:10px;right:10px;left:10px;width:auto;margin:0}.modal.fade.in{top:auto}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.762430939%;*margin-left:2.709239449638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.999999993%;*width:99.9468085036383%}.row-fluid .span11{width:91.436464082%;*width:91.38327259263829%}.row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%}.row-fluid .span9{width:74.30939226%;*width:74.25620077063829%}.row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%}.row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%}.row-fluid .span6{width:48.618784527%;*width:48.5655930376383%}.row-fluid .span5{width:40.055248616%;*width:40.0020571266383%}.row-fluid .span4{width:31.491712705%;*width:31.4385212156383%}.row-fluid .span3{width:22.928176794%;*width:22.874985304638297%}.row-fluid .span2{width:14.364640883%;*width:14.311449393638298%}.row-fluid .span1{width:5.801104972%;*width:5.747913482638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:714px}input.span11,textarea.span11,.uneditable-input.span11{width:652px}input.span10,textarea.span10,.uneditable-input.span10{width:590px}input.span9,textarea.span9,.uneditable-input.span9{width:528px}input.span8,textarea.span8,.uneditable-input.span8{width:466px}input.span7,textarea.span7,.uneditable-input.span7{width:404px}input.span6,textarea.span6,.uneditable-input.span6{width:342px}input.span5,textarea.span5,.uneditable-input.span5{width:280px}input.span4,textarea.span4,.uneditable-input.span4{width:218px}input.span3,textarea.span3,.uneditable-input.span3{width:156px}input.span2,textarea.span2,.uneditable-input.span2{width:94px}input.span1,textarea.span1,.uneditable-input.span1{width:32px}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.564102564%;*margin-left:2.510911074638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%}.row-fluid .span10{width:82.905982906%;*width:82.8527914166383%}.row-fluid .span9{width:74.358974359%;*width:74.30578286963829%}.row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%}.row-fluid .span7{width:57.264957265%;*width:57.2117657756383%}.row-fluid .span6{width:48.717948718%;*width:48.6647572286383%}.row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%}.row-fluid .span4{width:31.623931624%;*width:31.5707401346383%}.row-fluid .span3{width:23.076923077%;*width:23.0237315876383%}.row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%}.row-fluid .span1{width:5.982905983%;*width:5.929714493638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:1160px}input.span11,textarea.span11,.uneditable-input.span11{width:1060px}input.span10,textarea.span10,.uneditable-input.span10{width:960px}input.span9,textarea.span9,.uneditable-input.span9{width:860px}input.span8,textarea.span8,.uneditable-input.span8{width:760px}input.span7,textarea.span7,.uneditable-input.span7{width:660px}input.span6,textarea.span6,.uneditable-input.span6{width:560px}input.span5,textarea.span5,.uneditable-input.span5{width:460px}input.span4,textarea.span4,.uneditable-input.span4{width:360px}input.span3,textarea.span3,.uneditable-input.span3{width:260px}input.span2,textarea.span2,.uneditable-input.span2{width:160px}input.span1,textarea.span1,.uneditable-input.span1{width:60px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(max-width:767px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:18px}.navbar-fixed-bottom{margin-top:18px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#999;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222;border-bottom:1px solid #222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:768px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/Bench4Q-Web/src/main/webapp/css/jquery-ui-1.8.21.custom.css b/Bench4Q-Web/src/main/webapp/css/jquery-ui-1.8.21.custom.css deleted file mode 100644 index fcadf559..00000000 --- a/Bench4Q-Web/src/main/webapp/css/jquery-ui-1.8.21.custom.css +++ /dev/null @@ -1,565 +0,0 @@ -/*! - * jQuery UI CSS Framework 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and ../img */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/*! - * jQuery UI CSS Framework 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(../img/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(../img/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } -.ui-widget-header a { color: #222222; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(../img/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(../img/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(../img/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../img/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../img/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and ../img */ -.ui-icon { width: 16px; height: 16px; background-image: url(../img/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(../img/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(../img/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(../img/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(../img/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(../img/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(../img/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../img/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(../img/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../img/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! - * jQuery UI Resizable 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! - * jQuery UI Selectable 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/*! - * jQuery UI Accordion 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/*! - * jQuery UI Autocomplete 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.21 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/*! - * jQuery UI Button 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/*! - * jQuery UI Dialog 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/*! - * jQuery UI Slider 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! - * jQuery UI Tabs 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/*! - * jQuery UI Datepicker 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/*! - * jQuery UI Progressbar 1.8.21 - * - * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } diff --git a/Bench4Q-Web/src/main/webapp/homepage.jsp b/Bench4Q-Web/src/main/webapp/homepage.jsp index ebef8684..706d97c1 100644 --- a/Bench4Q-Web/src/main/webapp/homepage.jsp +++ b/Bench4Q-Web/src/main/webapp/homepage.jsp @@ -11,13 +11,18 @@ content="Bench4Q, a new method for QOS benchmarking."> - - - - - + + + + + - + @@ -66,11 +71,13 @@ - +
-

+

+ +

-
+
-

+

+ +

- + ID - + @@ -141,7 +150,7 @@ - + diff --git a/Bench4Q-Web/src/main/webapp/index.jsp b/Bench4Q-Web/src/main/webapp/index.jsp index d4072280..825a83a4 100644 --- a/Bench4Q-Web/src/main/webapp/index.jsp +++ b/Bench4Q-Web/src/main/webapp/index.jsp @@ -24,7 +24,7 @@ body { padding: 9px 0; } - + diff --git a/Bench4Q-Web/src/main/webapp/js/jsoneditor.css b/Bench4Q-Web/src/main/webapp/js/jsoneditor.css deleted file mode 100644 index 1f00b099..00000000 --- a/Bench4Q-Web/src/main/webapp/js/jsoneditor.css +++ /dev/null @@ -1,623 +0,0 @@ - -.jsoneditor .field, -.jsoneditor .value, -.jsoneditor .readonly { - border: 1px solid transparent; - min-height: 16px; - min-width: 32px; - padding: 2px; - margin: 1px; - word-wrap: break-word; - float: left; -} - -/* adjust margin of p elements inside editable divs, needed for Opera, IE */ -.jsoneditor .field p, -.jsoneditor .value p { - margin: 0; -} - -.jsoneditor .value { - word-break: break-word; -} - -.jsoneditor .readonly { - min-width: 16px; - color: gray; -} - -.jsoneditor .empty { - border-color: lightgray; - border-style: dashed; - border-radius: 2px; -} - -.jsoneditor .field.empty { - background-image: url('images/jsoneditor-icons.png'); - background-position: 0 -144px; -} - -.jsoneditor .value.empty { - background-image: url('images/jsoneditor-icons.png'); - background-position: -48px -144px; -} - -.jsoneditor .value.url { - color: green; - text-decoration: underline; -} - -.jsoneditor a.value.url:hover, -.jsoneditor a.value.url:focus { - color: red; -} - -.jsoneditor .separator { - padding: 3px 0; - vertical-align: top; - color: gray; -} - -.jsoneditor .field[contenteditable=true]:focus, -.jsoneditor .field[contenteditable=true]:hover, -.jsoneditor .value[contenteditable=true]:focus, -.jsoneditor .value[contenteditable=true]:hover, -.jsoneditor .field.highlight, -.jsoneditor .value.highlight { - background-color: #FFFFAB; - border: 1px solid yellow; - border-radius: 2px; -} - -.jsoneditor .field.highlight-active, -.jsoneditor .field.highlight-active:focus, -.jsoneditor .field.highlight-active:hover, -.jsoneditor .value.highlight-active, -.jsoneditor .value.highlight-active:focus, -.jsoneditor .value.highlight-active:hover { - background-color: #ffee00; - border: 1px solid #ffc700; - border-radius: 2px; -} - -.jsoneditor div.tree button { - width: 24px; - height: 24px; - padding: 0; - margin: 0; - border: none; - cursor: pointer; - background: transparent url('images/jsoneditor-icons.png'); -} - -.jsoneditor div.tree button.collapsed { - background-position: 0 -48px; -} - -.jsoneditor div.tree button.expanded { - background-position: 0 -72px; -} - -.jsoneditor div.tree button.contextmenu { - background-position: -48px -72px; -} - -.jsoneditor div.tree button.contextmenu:hover, -.jsoneditor div.tree button.contextmenu:focus, -.jsoneditor div.tree button.contextmenu.selected { - background-position: -48px -48px; -} - -.jsoneditor div.tree *:focus { - outline: none; -} - -.jsoneditor div.tree button:focus { - /* TODO: nice outline for buttons with focus - outline: #97B0F8 solid 2px; - box-shadow: 0 0 8px #97B0F8; - */ - background-color: #f5f5f5; - outline: #e5e5e5 solid 1px; -} - -.jsoneditor div.tree button.invisible { - visibility: hidden; - background: none; -} - -.jsoneditor { - color: #1A1A1A; - border: 1px solid #cacccc; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - - width: 100%; - height: 100%; - overflow: auto; - position: relative; - padding: 0; - line-height: 100%; -} - - -.jsoneditor div.tree table.tree { - border-collapse: collapse; - border-spacing: 0; - width: 100%; - margin: 0; -} - -.jsoneditor div.outer { - width: 100%; - height: 100%; - margin: -35px 0 0 0; - padding: 35px 0 0 0; - - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - - overflow: hidden; -} - -.jsoneditor div.tree { - width: 100%; - height: 100%; - position: relative; - overflow: auto; -} - -.jsoneditor textarea.text { - width: 100%; - height: 100%; - margin: 0; - - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - - border: none; - background-color: white; - resize: none; -} - -.jsoneditor tr.highlight { - background-color: #FFFFAB; -} - -.jsoneditor div.tree button.dragarea { - background: url('images/jsoneditor-icons.png') -72px -72px; - cursor: move; -} - -.jsoneditor div.tree button.dragarea:hover, -.jsoneditor div.tree button.dragarea:focus { - background-position: -72px -48px; -} - -.jsoneditor tr, -.jsoneditor th, -.jsoneditor td { - padding: 0; - margin: 0; -} - -.jsoneditor td { - vertical-align: top; -} - -.jsoneditor td.tree { - vertical-align: top; -} - -.jsoneditor .field, -.jsoneditor .value, -.jsoneditor td, -.jsoneditor th, -.jsoneditor textarea { - font-family: droid sans mono, monospace, courier new, courier, sans-serif; - font-size: 10pt; - color: #1A1A1A; -} - - -/* ContextMenu - main menu */ - -.jsoneditor-contextmenu { - position: absolute; - z-index: 99999; -} - -.jsoneditor-contextmenu ul { - position: relative; - left: 0; - top: 0; - width: 124px; - - background: white; - border: 1px solid #d3d3d3; - box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); - - list-style: none; - margin: 0; - padding: 0; -} - -.jsoneditor-contextmenu ul li button { - padding: 0; - margin: 0; - width: 124px; - height: 24px; - border: none; - cursor: pointer; - color: #4d4d4d; - background: transparent; - - line-height: 26px; - text-align: left; -} - -/* Fix button padding in firefox */ -.jsoneditor-contextmenu ul li button::-moz-focus-inner { - padding: 0; - border: 0; -} - -.jsoneditor-contextmenu ul li button:hover, -.jsoneditor-contextmenu ul li button:focus { - color: #1a1a1a; - background-color: #f5f5f5; - outline: none; -} - -.jsoneditor-contextmenu ul li button.default { - width: 92px; -} - -.jsoneditor-contextmenu ul li button.expand { - float: right; - width: 32px; - height: 24px; - border-left: 1px solid #e5e5e5; -} - -.jsoneditor-contextmenu div.icon { - float: left; - width: 24px; - height: 24px; - border: none; - padding: 0; - margin: 0; - background-image: url('images/jsoneditor-icons.png'); -} - -.jsoneditor-contextmenu ul li button div.expand { - float: right; - width: 24px; - height: 24px; - padding: 0; - margin: 0 4px 0 0; - background: url('images/jsoneditor-icons.png') 0 -72px; - opacity: 0.4; -} - -.jsoneditor-contextmenu ul li button:hover div.expand, -.jsoneditor-contextmenu ul li button:focus div.expand, -.jsoneditor-contextmenu ul li.selected div.expand, -.jsoneditor-contextmenu ul li button.expand:hover div.expand, -.jsoneditor-contextmenu ul li button.expand:focus div.expand { - opacity: 1; -} - -.jsoneditor-contextmenu .separator { - height: 0; - border-top: 1px solid #e5e5e5; - padding-top: 5px; - margin-top: 5px; -} - -.jsoneditor-contextmenu button.remove > .icon { - background-position: -24px -24px; -} -.jsoneditor-contextmenu button.remove:hover > .icon, -.jsoneditor-contextmenu button.remove:focus > .icon { - background-position: -24px 0; -} - -.jsoneditor-contextmenu button.append > .icon { - background-position: 0 -24px; -} -.jsoneditor-contextmenu button.append:hover > .icon, -.jsoneditor-contextmenu button.append:focus > .icon { - background-position: 0 0; -} - -.jsoneditor-contextmenu button.insert > .icon { - background-position: 0 -24px; -} -.jsoneditor-contextmenu button.insert:hover > .icon, -.jsoneditor-contextmenu button.insert:focus > .icon { - background-position: 0 0; -} - -.jsoneditor-contextmenu button.duplicate > .icon { - background-position: -48px -24px; -} -.jsoneditor-contextmenu button.duplicate:hover > .icon, -.jsoneditor-contextmenu button.duplicate:focus > .icon { - background-position: -48px 0; -} - -.jsoneditor-contextmenu button.sort-asc > .icon { - background-position: -168px -24px; -} -.jsoneditor-contextmenu button.sort-asc:hover > .icon, -.jsoneditor-contextmenu button.sort-asc:focus > .icon { - background-position: -168px 0; -} - -.jsoneditor-contextmenu button.sort-desc > .icon { - background-position: -192px -24px; -} -.jsoneditor-contextmenu button.sort-desc:hover > .icon, -.jsoneditor-contextmenu button.sort-desc:focus > .icon { - background-position: -192px 0; -} - -/* ContextMenu - sub menu */ - -.jsoneditor-contextmenu ul li .selected { - background-color: #D5DDF6; -} - -.jsoneditor-contextmenu ul li { - overflow: hidden; -} - -.jsoneditor-contextmenu ul li ul { - display: none; - position: relative; - left: -10px; - top: 0; - - border: none; - box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5); - padding: 0 10px; - - /* TODO: transition is not supported on IE8-9 */ - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; -} - -.jsoneditor-contextmenu ul li.selected ul { -} - -.jsoneditor-contextmenu ul li ul li button { - padding-left: 24px; -} - -.jsoneditor-contextmenu ul li ul li button:hover, -.jsoneditor-contextmenu ul li ul li button:focus { - background-color: #f5f5f5; - -} - -.jsoneditor-contextmenu button.type-string > .icon { - background-position: -144px -24px; -} -.jsoneditor-contextmenu button.type-string:hover > .icon, -.jsoneditor-contextmenu button.type-string:focus > .icon, -.jsoneditor-contextmenu button.type-string.selected > .icon{ - background-position: -144px 0; -} - -.jsoneditor-contextmenu button.type-auto > .icon { - background-position: -120px -24px; -} -.jsoneditor-contextmenu button.type-auto:hover > .icon, -.jsoneditor-contextmenu button.type-auto:focus > .icon, -.jsoneditor-contextmenu button.type-auto.selected > .icon { - background-position: -120px 0; -} - -.jsoneditor-contextmenu button.type-object > .icon { - background-position: -72px -24px; -} -.jsoneditor-contextmenu button.type-object:hover > .icon, -.jsoneditor-contextmenu button.type-object:focus > .icon, -.jsoneditor-contextmenu button.type-object.selected > .icon{ - background-position: -72px 0; -} - -.jsoneditor-contextmenu button.type-array > .icon { - background-position: -96px -24px; -} -.jsoneditor-contextmenu button.type-array:hover > .icon, -.jsoneditor-contextmenu button.type-array:focus > .icon, -.jsoneditor-contextmenu button.type-array.selected > .icon{ - background-position: -96px 0; -} - -.jsoneditor-contextmenu button.type-modes > .icon { - background-image: none; - width: 6px; -} - - -.jsoneditor .menu { - width: 100%; - height: 35px; - padding: 2px; - margin: 0; - overflow: hidden; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - - color: #1A1A1A; - background-color: #f7f7f9; - border-bottom: 1px solid #e1e1e8; -} - -.jsoneditor .menu button { - width: 26px; - height: 26px; - margin: 2px; - padding: 0; - border-radius: 2px; - border: 1px solid #D5D5D5; - background: #D5D5D5 url('images/jsoneditor-icons.png'); - color: #4D4D4D; - opacity: 0.8; - - font-family: arial, sans-serif; - font-size: 10pt; - - float: left; -} - -.jsoneditor .menu button:hover { - background-color: #f0f2f5; -} -.jsoneditor .menu button:active { - background-color: #ffffff; -} -.jsoneditor .menu button:disabled { - background-color: #e3eaf6; -} - -.jsoneditor .menu button.collapse-all { - background-position: 0 -96px; -} -.jsoneditor .menu button.expand-all { - background-position: 0 -120px; -} -.jsoneditor .menu button.undo { - background-position: -24px -96px; -} -.jsoneditor .menu button.undo:disabled { - background-position: -24px -120px; -} -.jsoneditor .menu button.redo { - background-position: -48px -96px; -} -.jsoneditor .menu button.redo:disabled { - background-position: -48px -120px; -} -.jsoneditor .menu button.compact { - background-position: -72px -96px; -} -.jsoneditor .menu button.format { - background-position: -72px -120px; -} - -.jsoneditor .menu button.modes { - background-image: none; - width: auto; - padding-left: 6px; - padding-right: 6px; -} - -.jsoneditor .menu button.separator { - margin-left: 10px; -} - -.jsoneditor .menu a { - font-family: arial, sans-serif; - font-size: 10pt; - color: #97B0F8; - vertical-align: middle; -} - -.jsoneditor .menu a:hover { - color: red; -} - -.jsoneditor .menu a.poweredBy { - font-size: 8pt; - position: absolute; - right: 0; - top: 0; - padding: 10px; -} - -/* TODO: css for button:disabled is not supported by IE8 */ - - -.jsoneditor .search input, -.jsoneditor .search .results { - font-family: arial, sans-serif; - font-size: 10pt; - color: #1A1A1A; -} - -.jsoneditor .search { - position: absolute; - right: 2px; - top: 2px; -} - -.jsoneditor .search .frame { - border: 1px solid #97B0F8; - background-color: white; - padding: 0 2px; - margin: 0; -} - -.jsoneditor .search .frame table { - border-collapse: collapse; -} - -.jsoneditor .search input { - width: 120px; - border: none; - outline: none; - margin: 1px; -} - -.jsoneditor .search .results { - color: #4d4d4d; - padding-right: 5px; - line-height: 24px; -} - -.jsoneditor .search button { - width: 16px; - height: 24px; - padding: 0; - margin: 0; - border: none; - background: url('images/jsoneditor-icons.png'); - vertical-align: top; -} - -.jsoneditor .search button:hover { - background-color: transparent; -} - -.jsoneditor .search button.refresh { - width: 18px; - background-position: -99px -73px; -} - -.jsoneditor .search button.next { - cursor: pointer; - background-position: -124px -73px; -} -.jsoneditor .search button.next:hover { - background-position: -124px -49px; -} - -.jsoneditor .search button.previous { - cursor: pointer; - background-position: -148px -73px; - margin-right: 2px; -} -.jsoneditor .search button.previous:hover { - background-position: -148px -49px; -} - diff --git a/Bench4Q-Web/src/main/webapp/js/jsoneditor.js b/Bench4Q-Web/src/main/webapp/js/jsoneditor.js deleted file mode 100644 index 936efef0..00000000 --- a/Bench4Q-Web/src/main/webapp/js/jsoneditor.js +++ /dev/null @@ -1,6029 +0,0 @@ -/*! - * jsoneditor.js - * - * @brief - * JSONEditor is a web-based tool to view, edit, and format JSON. - * It shows data a clear, editable treeview. - * - * Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+ - * - * @license - * This json editor is open sourced with the intention to use the editor as - * a component in your own application. Not to just copy and monetize the editor - * as it is. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - * - * Copyright (c) 2011-2013 Jos de Jong, http://jsoneditoronline.org - * - * @author Jos de Jong, - * @version 2.3.5 - * @date 2013-12-09 - */ -(function () { - -/** - * @constructor JSONEditor - * @param {Element} container Container element - * @param {Object} [options] Object with options. available options: - * {String} mode Editor mode. Available values: - * 'tree' (default), 'view', - * 'form', 'text', and 'code'. - * {function} change Callback method, triggered - * on change of contents - * {Boolean} search Enable search box. - * True by default - * Only applicable for modes - * 'tree', 'view', and 'form' - * {Boolean} history Enable history (undo/redo). - * True by default - * Only applicable for modes - * 'tree', 'view', and 'form' - * {String} name Field name for the root node. - * Only applicable for modes - * 'tree', 'view', and 'form' - * {Number} indentation Number of indentation - * spaces. 4 by default. - * Only applicable for - * modes 'text' and 'code' - * @param {Object | undefined} json JSON object - */ -function JSONEditor (container, options, json) { - if (!(this instanceof JSONEditor)) { - throw new Error('JSONEditor constructor called without "new".'); - } - - // check for unsupported browser (IE8 and older) - var ieVersion = util.getInternetExplorerVersion(); - if (ieVersion != -1 && ieVersion < 9) { - throw new Error('Unsupported browser, IE9 or newer required. ' + - 'Please install the newest version of your browser.'); - } - - if (arguments.length) { - this._create(container, options, json); - } -} - -/** - * Configuration for all registered modes. Example: - * { - * tree: { - * editor: TreeEditor, - * data: 'json' - * }, - * text: { - * editor: TextEditor, - * data: 'text' - * } - * } - * - * @type { Object. } - */ -JSONEditor.modes = {}; - -/** - * Create the JSONEditor - * @param {Element} container Container element - * @param {Object} [options] See description in constructor - * @param {Object | undefined} json JSON object - * @private - */ -JSONEditor.prototype._create = function (container, options, json) { - this.container = container; - this.options = options || {}; - this.json = json || {}; - - var mode = this.options.mode || 'tree'; - this.setMode(mode); -}; - -/** - * Detach the editor from the DOM - * @private - */ -JSONEditor.prototype._delete = function () {}; - -/** - * Set JSON object in editor - * @param {Object | undefined} json JSON data - */ -JSONEditor.prototype.set = function (json) { - this.json = json; -}; - -/** - * Get JSON from the editor - * @returns {Object} json - */ -JSONEditor.prototype.get = function () { - return this.json; -}; - -/** - * Set string containing JSON for the editor - * @param {String | undefined} jsonText - */ -JSONEditor.prototype.setText = function (jsonText) { - this.json = util.parse(jsonText); -}; - -/** - * Get stringified JSON contents from the editor - * @returns {String} jsonText - */ -JSONEditor.prototype.getText = function () { - return JSON.stringify(this.json); -}; - -/** - * Set a field name for the root node. - * @param {String | undefined} name - */ -JSONEditor.prototype.setName = function (name) { - if (!this.options) { - this.options = {}; - } - this.options.name = name; -}; - -/** - * Get the field name for the root node. - * @return {String | undefined} name - */ -JSONEditor.prototype.getName = function () { - return this.options && this.options.name; -}; - -/** - * Change the mode of the editor. - * JSONEditor will be extended with all methods needed for the chosen mode. - * @param {String} mode Available modes: 'tree' (default), 'view', 'form', - * 'text', and 'code'. - */ -JSONEditor.prototype.setMode = function (mode) { - var container = this.container, - options = util.extend({}, this.options), - data, - name; - - options.mode = mode; - var config = JSONEditor.modes[mode]; - if (config) { - try { - if (config.data == 'text') { - // text - name = this.getName(); - data = this.getText(); - - this._delete(); - util.clear(this); - util.extend(this, config.editor.prototype); - this._create(container, options); - - this.setName(name); - this.setText(data); - } - else { - // json - name = this.getName(); - data = this.get(); - - this._delete(); - util.clear(this); - util.extend(this, config.editor.prototype); - this._create(container, options); - - this.setName(name); - this.set(data); - } - - if (typeof config.load === 'function') { - try { - config.load.call(this); - } - catch (err) {} - } - } - catch (err) { - this._onError(err); - } - } - else { - throw new Error('Unknown mode "' + options.mode + '"'); - } -}; - -/** - * Throw an error. If an error callback is configured in options.error, this - * callback will be invoked. Else, a regular error is thrown. - * @param {Error} err - * @private - */ -JSONEditor.prototype._onError = function(err) { - // TODO: onError is deprecated since version 2.2.0. cleanup some day - if (typeof this.onError === 'function') { - util.log('WARNING: JSONEditor.onError is deprecated. ' + - 'Use options.error instead.'); - this.onError(err); - } - - if (this.options && typeof this.options.error === 'function') { - this.options.error(err); - } - else { - throw err; - } -}; - -/** - * @constructor TreeEditor - * @param {Element} container Container element - * @param {Object} [options] Object with options. available options: - * {String} mode Editor mode. Available values: - * 'tree' (default), 'view', - * and 'form'. - * {Boolean} search Enable search box. - * True by default - * {Boolean} history Enable history (undo/redo). - * True by default - * {function} change Callback method, triggered - * on change of contents - * {String} name Field name for the root node. - * @param {Object | undefined} json JSON object - */ -function TreeEditor(container, options, json) { - if (!(this instanceof TreeEditor)) { - throw new Error('TreeEditor constructor called without "new".'); - } - - this._create(container, options, json); -} - -/** - * Create the TreeEditor - * @param {Element} container Container element - * @param {Object} [options] See description in constructor - * @param {Object | undefined} json JSON object - * @private - */ -TreeEditor.prototype._create = function (container, options, json) { - if (!container) { - throw new Error('No container element provided.'); - } - this.container = container; - this.dom = {}; - this.highlighter = new Highlighter(); - this.selection = undefined; // will hold the last input selection - - this._setOptions(options); - - if (this.options.history && !this.mode.view) { - this.history = new History(this); - } - - this._createFrame(); - this._createTable(); - - this.set(json || {}); -}; - -/** - * Detach the editor from the DOM - * @private - */ -TreeEditor.prototype._delete = function () { - if (this.frame && this.container && this.frame.parentNode == this.container) { - this.container.removeChild(this.frame); - } -}; - -/** - * Initialize and set default options - * @param {Object} [options] See description in constructor - * @private - */ -TreeEditor.prototype._setOptions = function (options) { - this.options = { - search: true, - history: true, - mode: 'tree', - name: undefined // field name of root node - }; - - // copy all options - if (options) { - for (var prop in options) { - if (options.hasOwnProperty(prop)) { - this.options[prop] = options[prop]; - } - } - - // check for deprecated options - if (options['enableSearch']) { - // deprecated since version 1.6.0, 2012-11-03 - this.options.search = options['enableSearch']; - util.log('WARNING: Option "enableSearch" is deprecated. Use "search" instead.'); - } - if (options['enableHistory']) { - // deprecated since version 1.6.0, 2012-11-03 - this.options.history = options['enableHistory']; - util.log('WARNING: Option "enableHistory" is deprecated. Use "history" instead.'); - } - if (options['mode'] == 'editor') { - // deprecated since version 2.2.0, 2013-04-30 - this.options.mode = 'tree'; - util.log('WARNING: Mode "editor" is deprecated. Use "tree" instead.'); - } - if (options['mode'] == 'viewer') { - // deprecated since version 2.2.0, 2013-04-30 - this.options.mode = 'view'; - util.log('WARNING: Mode "viewer" is deprecated. Use "view" instead.'); - } - } - - // interpret the mode options - this.mode = { - edit: (this.options.mode != 'view' && this.options.mode != 'form'), - view: (this.options.mode == 'view'), - form: (this.options.mode == 'form') - }; -}; - -// node currently being edited -TreeEditor.focusNode = undefined; - -/** - * Set JSON object in editor - * @param {Object | undefined} json JSON data - * @param {String} [name] Optional field name for the root node. - * Can also be set using setName(name). - */ -TreeEditor.prototype.set = function (json, name) { - // adjust field name for root node - if (name) { - // TODO: deprecated since version 2.2.0. Cleanup some day. - util.log('Warning: second parameter "name" is deprecated. ' + - 'Use setName(name) instead.'); - this.options.name = name; - } - - // verify if json is valid JSON, ignore when a function - if (json instanceof Function || (json === undefined)) { - this.clear(); - } - else { - this.content.removeChild(this.table); // Take the table offline - - // replace the root node - var params = { - 'field': this.options.name, - 'value': json - }; - var node = new Node(this, params); - this._setRoot(node); - - // expand - var recurse = false; - this.node.expand(recurse); - - this.content.appendChild(this.table); // Put the table online again - } - - // TODO: maintain history, store last state and previous document - if (this.history) { - this.history.clear(); - } -}; - -/** - * Get JSON object from editor - * @return {Object | undefined} json - */ -TreeEditor.prototype.get = function () { - // remove focus from currently edited node - if (TreeEditor.focusNode) { - TreeEditor.focusNode.blur(); - } - - if (this.node) { - return this.node.getValue(); - } - else { - return undefined; - } -}; - -/** - * Get the text contents of the TreeEditor - * @return {String} jsonText - */ -TreeEditor.prototype.getText = function() { - return JSON.stringify(this.get()); -}; - -/** - * Set the text contents of the TreeEditor - * @param {String} jsonText - */ -TreeEditor.prototype.setText = function(jsonText) { - this.set(util.parse(jsonText)); -}; - -/** - * Set a field name for the root node. - * @param {String | undefined} name - */ -TreeEditor.prototype.setName = function (name) { - this.options.name = name; - if (this.node) { - this.node.updateField(this.options.name); - } -}; - -/** - * Get the field name for the root node. - * @return {String | undefined} name - */ -TreeEditor.prototype.getName = function () { - return this.options.name; -}; - -/** - * Remove the root node from the editor - */ -TreeEditor.prototype.clear = function () { - if (this.node) { - this.node.collapse(); - this.tbody.removeChild(this.node.getDom()); - delete this.node; - } -}; - -/** - * Set the root node for the json editor - * @param {Node} node - * @private - */ -TreeEditor.prototype._setRoot = function (node) { - this.clear(); - - this.node = node; - - // append to the dom - this.tbody.appendChild(node.getDom()); -}; - -/** - * Search text in all nodes - * The nodes will be expanded when the text is found one of its childs, - * else it will be collapsed. Searches are case insensitive. - * @param {String} text - * @return {Object[]} results Array with nodes containing the search results - * The result objects contains fields: - * - {Node} node, - * - {String} elem the dom element name where - * the result is found ('field' or - * 'value') - */ -TreeEditor.prototype.search = function (text) { - var results; - if (this.node) { - this.content.removeChild(this.table); // Take the table offline - results = this.node.search(text); - this.content.appendChild(this.table); // Put the table online again - } - else { - results = []; - } - - return results; -}; - -/** - * Expand all nodes - */ -TreeEditor.prototype.expandAll = function () { - if (this.node) { - this.content.removeChild(this.table); // Take the table offline - this.node.expand(); - this.content.appendChild(this.table); // Put the table online again - } -}; - -/** - * Collapse all nodes - */ -TreeEditor.prototype.collapseAll = function () { - if (this.node) { - this.content.removeChild(this.table); // Take the table offline - this.node.collapse(); - this.content.appendChild(this.table); // Put the table online again - } -}; - -/** - * The method onChange is called whenever a field or value is changed, created, - * deleted, duplicated, etc. - * @param {String} action Change action. Available values: "editField", - * "editValue", "changeType", "appendNode", - * "removeNode", "duplicateNode", "moveNode", "expand", - * "collapse". - * @param {Object} params Object containing parameters describing the change. - * The parameters in params depend on the action (for - * example for "editValue" the Node, old value, and new - * value are provided). params contains all information - * needed to undo or redo the action. - * @private - */ -TreeEditor.prototype._onAction = function (action, params) { - // add an action to the history - if (this.history) { - this.history.add(action, params); - } - - // trigger the onChange callback - if (this.options.change) { - try { - this.options.change(); - } - catch (err) { - util.log('Error in change callback: ', err); - } - } -}; - -/** - * Start autoscrolling when given mouse position is above the top of the - * editor contents, or below the bottom. - * @param {Number} mouseY Absolute mouse position in pixels - */ -TreeEditor.prototype.startAutoScroll = function (mouseY) { - var me = this; - var content = this.content; - var top = util.getAbsoluteTop(content); - var height = content.clientHeight; - var bottom = top + height; - var margin = 24; - var interval = 50; // ms - - if ((mouseY < top + margin) && content.scrollTop > 0) { - this.autoScrollStep = ((top + margin) - mouseY) / 3; - } - else if (mouseY > bottom - margin && - height + content.scrollTop < content.scrollHeight) { - this.autoScrollStep = ((bottom - margin) - mouseY) / 3; - } - else { - this.autoScrollStep = undefined; - } - - if (this.autoScrollStep) { - if (!this.autoScrollTimer) { - this.autoScrollTimer = setInterval(function () { - if (me.autoScrollStep) { - content.scrollTop -= me.autoScrollStep; - } - else { - me.stopAutoScroll(); - } - }, interval); - } - } - else { - this.stopAutoScroll(); - } -}; - -/** - * Stop auto scrolling. Only applicable when scrolling - */ -TreeEditor.prototype.stopAutoScroll = function () { - if (this.autoScrollTimer) { - clearTimeout(this.autoScrollTimer); - delete this.autoScrollTimer; - } - if (this.autoScrollStep) { - delete this.autoScrollStep; - } -}; - - -/** - * Set the focus to an element in the TreeEditor, set text selection, and - * set scroll position. - * @param {Object} selection An object containing fields: - * {Element | undefined} dom The dom element - * which has focus - * {Range | TextRange} range A text selection - * {Number} scrollTop Scroll position - */ -TreeEditor.prototype.setSelection = function (selection) { - if (!selection) { - return; - } - - if ('scrollTop' in selection && this.content) { - // TODO: animated scroll - this.content.scrollTop = selection.scrollTop; - } - if (selection.range) { - util.setSelectionOffset(selection.range); - } - if (selection.dom) { - selection.dom.focus(); - } -}; - -/** - * Get the current focus - * @return {Object} selection An object containing fields: - * {Element | undefined} dom The dom element - * which has focus - * {Range | TextRange} range A text selection - * {Number} scrollTop Scroll position - */ -TreeEditor.prototype.getSelection = function () { - return { - dom: TreeEditor.domFocus, - scrollTop: this.content ? this.content.scrollTop : 0, - range: util.getSelectionOffset() - }; -}; - -/** - * Adjust the scroll position such that given top position is shown at 1/4 - * of the window height. - * @param {Number} top - * @param {function(boolean)} [callback] Callback, executed when animation is - * finished. The callback returns true - * when animation is finished, or false - * when not. - */ -TreeEditor.prototype.scrollTo = function (top, callback) { - var content = this.content; - if (content) { - var editor = this; - // cancel any running animation - if (editor.animateTimeout) { - clearTimeout(editor.animateTimeout); - delete editor.animateTimeout; - } - if (editor.animateCallback) { - editor.animateCallback(false); - delete editor.animateCallback; - } - - // calculate final scroll position - var height = content.clientHeight; - var bottom = content.scrollHeight - height; - var finalScrollTop = Math.min(Math.max(top - height / 4, 0), bottom); - - // animate towards the new scroll position - var animate = function () { - var scrollTop = content.scrollTop; - var diff = (finalScrollTop - scrollTop); - if (Math.abs(diff) > 3) { - content.scrollTop += diff / 3; - editor.animateCallback = callback; - editor.animateTimeout = setTimeout(animate, 50); - } - else { - // finished - if (callback) { - callback(true); - } - content.scrollTop = finalScrollTop; - delete editor.animateTimeout; - delete editor.animateCallback; - } - }; - animate(); - } - else { - if (callback) { - callback(false); - } - } -}; - -/** - * Create main frame - * @private - */ -TreeEditor.prototype._createFrame = function () { - // create the frame - this.frame = document.createElement('div'); - this.frame.className = 'jsoneditor'; - this.container.appendChild(this.frame); - - // create one global event listener to handle all events from all nodes - var editor = this; - var onEvent = function (event) { - editor._onEvent(event); - }; - this.frame.onclick = function (event) { - var target = event.target;// || event.srcElement; - - onEvent(event); - - // prevent default submit action of buttons when TreeEditor is located - // inside a form - if (target.nodeName == 'BUTTON') { - event.preventDefault(); - } - }; - this.frame.oninput = onEvent; - this.frame.onchange = onEvent; - this.frame.onkeydown = onEvent; - this.frame.onkeyup = onEvent; - this.frame.oncut = onEvent; - this.frame.onpaste = onEvent; - this.frame.onmousedown = onEvent; - this.frame.onmouseup = onEvent; - this.frame.onmouseover = onEvent; - this.frame.onmouseout = onEvent; - // Note: focus and blur events do not propagate, therefore they defined - // using an eventListener with useCapture=true - // see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - util.addEventListener(this.frame, 'focus', onEvent, true); - util.addEventListener(this.frame, 'blur', onEvent, true); - this.frame.onfocusin = onEvent; // for IE - this.frame.onfocusout = onEvent; // for IE - - // create menu - this.menu = document.createElement('div'); - this.menu.className = 'menu'; - this.frame.appendChild(this.menu); - - // create expand all button - var expandAll = document.createElement('button'); - expandAll.className = 'expand-all'; - expandAll.title = 'Expand all fields'; - expandAll.onclick = function () { - editor.expandAll(); - }; - this.menu.appendChild(expandAll); - - // create expand all button - var collapseAll = document.createElement('button'); - collapseAll.title = 'Collapse all fields'; - collapseAll.className = 'collapse-all'; - collapseAll.onclick = function () { - editor.collapseAll(); - }; - this.menu.appendChild(collapseAll); - - // create undo/redo buttons - if (this.history) { - // create undo button - var undo = document.createElement('button'); - undo.className = 'undo separator'; - undo.title = 'Undo last action (Ctrl+Z)'; - undo.onclick = function () { - editor._onUndo(); - }; - this.menu.appendChild(undo); - this.dom.undo = undo; - - // create redo button - var redo = document.createElement('button'); - redo.className = 'redo'; - redo.title = 'Redo (Ctrl+Shift+Z)'; - redo.onclick = function () { - editor._onRedo(); - }; - this.menu.appendChild(redo); - this.dom.redo = redo; - - // register handler for onchange of history - this.history.onChange = function () { - undo.disabled = !editor.history.canUndo(); - redo.disabled = !editor.history.canRedo(); - }; - this.history.onChange(); - } - - // create mode box - if (this.options && this.options.modes && this.options.modes.length) { - var modeBox = createModeBox(this, this.options.modes, this.options.mode); - this.menu.appendChild(modeBox); - this.dom.modeBox = modeBox; - } - - // create search box - if (this.options.search) { - this.searchBox = new SearchBox(this, this.menu); - } -}; - -/** - * Perform an undo action - * @private - */ -TreeEditor.prototype._onUndo = function () { - if (this.history) { - // undo last action - this.history.undo(); - - // trigger change callback - if (this.options.change) { - this.options.change(); - } - } -}; - -/** - * Perform a redo action - * @private - */ -TreeEditor.prototype._onRedo = function () { - if (this.history) { - // redo last action - this.history.redo(); - - // trigger change callback - if (this.options.change) { - this.options.change(); - } - } -}; - -/** - * Event handler - * @param event - * @private - */ -TreeEditor.prototype._onEvent = function (event) { - var target = event.target; - - if (event.type == 'keydown') { - this._onKeyDown(event); - } - - if (event.type == 'focus') { - TreeEditor.domFocus = target; - } - - var node = Node.getNodeFromTarget(target); - if (node) { - node.onEvent(event); - } -}; - -/** - * Event handler for keydown. Handles shortcut keys - * @param {Event} event - * @private - */ -TreeEditor.prototype._onKeyDown = function (event) { - var keynum = event.which || event.keyCode; - var ctrlKey = event.ctrlKey; - var shiftKey = event.shiftKey; - var handled = false; - - if (keynum == 9) { // Tab or Shift+Tab - setTimeout(function () { - // select all text when moving focus to an editable div - util.selectContentEditable(TreeEditor.domFocus); - }, 0); - } - - if (this.searchBox) { - if (ctrlKey && keynum == 70) { // Ctrl+F - this.searchBox.dom.search.focus(); - this.searchBox.dom.search.select(); - handled = true; - } - else if (keynum == 114 || (ctrlKey && keynum == 71)) { // F3 or Ctrl+G - var focus = true; - if (!shiftKey) { - // select next search result (F3 or Ctrl+G) - this.searchBox.next(focus); - } - else { - // select previous search result (Shift+F3 or Ctrl+Shift+G) - this.searchBox.previous(focus); - } - - handled = true; - } - } - - if (this.history) { - if (ctrlKey && !shiftKey && keynum == 90) { // Ctrl+Z - // undo - this._onUndo(); - handled = true; - } - else if (ctrlKey && shiftKey && keynum == 90) { // Ctrl+Shift+Z - // redo - this._onRedo(); - handled = true; - } - } - - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } -}; - -/** - * Create main table - * @private - */ -TreeEditor.prototype._createTable = function () { - var contentOuter = document.createElement('div'); - contentOuter.className = 'outer'; - this.contentOuter = contentOuter; - - this.content = document.createElement('div'); - this.content.className = 'tree'; - contentOuter.appendChild(this.content); - - this.table = document.createElement('table'); - this.table.className = 'tree'; - this.content.appendChild(this.table); - - // create colgroup where the first two columns don't have a fixed - // width, and the edit columns do have a fixed width - var col; - this.colgroupContent = document.createElement('colgroup'); - if (this.mode.edit) { - col = document.createElement('col'); - col.width = "24px"; - this.colgroupContent.appendChild(col); - } - col = document.createElement('col'); - col.width = "24px"; - this.colgroupContent.appendChild(col); - col = document.createElement('col'); - this.colgroupContent.appendChild(col); - this.table.appendChild(this.colgroupContent); - - this.tbody = document.createElement('tbody'); - this.table.appendChild(this.tbody); - - this.frame.appendChild(contentOuter); -}; - -// register modes at the JSONEditor -JSONEditor.modes.tree = { - editor: TreeEditor, - data: 'json' -}; -JSONEditor.modes.view = { - editor: TreeEditor, - data: 'json' -}; -JSONEditor.modes.form = { - editor: TreeEditor, - data: 'json' -}; -// Deprecated modes (deprecated since version 2.2.0) -JSONEditor.modes.editor = { - editor: TreeEditor, - data: 'json' -}; -JSONEditor.modes.viewer = { - editor: TreeEditor, - data: 'json' -}; - -/** - * Create a TextEditor and attach it to given container - * @constructor TextEditor - * @param {Element} container - * @param {Object} [options] Object with options. available options: - * {String} mode Available values: - * "text" (default) - * or "code". - * {Number} indentation Number of indentation - * spaces. 4 by default. - * {function} change Callback method - * triggered on change - * @param {JSON | String} [json] initial contents of the formatter - */ -function TextEditor(container, options, json) { - if (!(this instanceof TextEditor)) { - throw new Error('TextEditor constructor called without "new".'); - } - - this._create(container, options, json); -} - -/** - * Create a TextEditor and attach it to given container - * @constructor TextEditor - * @param {Element} container - * @param {Object} [options] See description in constructor - * @param {JSON | String} [json] initial contents of the formatter - * @private - */ -TextEditor.prototype._create = function (container, options, json) { - // read options - options = options || {}; - this.options = options; - if (options.indentation) { - this.indentation = Number(options.indentation); - } - else { - this.indentation = 2; // number of spaces - } - this.mode = (options.mode == 'code') ? 'code' : 'text'; - if (this.mode == 'code') { - // verify whether Ace editor is available and supported - if (typeof ace === 'undefined') { - this.mode = 'text'; - util.log('WARNING: Cannot load code editor, Ace library not loaded. ' + - 'Falling back to plain text editor'); - } - } - - var me = this; - this.container = container; - this.dom = {}; - this.editor = undefined; // ace code editor - this.textarea = undefined; // plain text editor (fallback when Ace is not available) - - this.width = container.clientWidth; - this.height = container.clientHeight; - - this.frame = document.createElement('div'); - this.frame.className = 'jsoneditor'; - this.frame.onclick = function (event) { - // prevent default submit action when TextEditor is located inside a form - event.preventDefault(); - }; - - // create menu - this.menu = document.createElement('div'); - this.menu.className = 'menu'; - this.frame.appendChild(this.menu); - - // create format button - var buttonFormat = document.createElement('button'); - buttonFormat.className = 'format'; - buttonFormat.title = 'Format JSON data, with proper indentation and line feeds'; - this.menu.appendChild(buttonFormat); - buttonFormat.onclick = function () { - try { - me.format(); - } - catch (err) { - me._onError(err); - } - }; - - // create compact button - var buttonCompact = document.createElement('button'); - buttonCompact.className = 'compact'; - buttonCompact.title = 'Compact JSON data, remove all whitespaces'; - this.menu.appendChild(buttonCompact); - buttonCompact.onclick = function () { - try { - me.compact(); - } - catch (err) { - me._onError(err); - } - }; - - // create mode box - if (this.options && this.options.modes && this.options.modes.length) { - var modeBox = createModeBox(this, this.options.modes, this.options.mode); - this.menu.appendChild(modeBox); - this.dom.modeBox = modeBox; - } - - this.content = document.createElement('div'); - this.content.className = 'outer'; - this.frame.appendChild(this.content); - - this.container.appendChild(this.frame); - - if (this.mode == 'code') { - this.editorDom = document.createElement('div'); - this.editorDom.style.height = '100%'; // TODO: move to css - this.editorDom.style.width = '100%'; // TODO: move to css - this.content.appendChild(this.editorDom); - - var editor = ace.edit(this.editorDom); - editor.setTheme('ace/theme/jsoneditor'); - editor.setShowPrintMargin(false); - editor.setFontSize(13); - editor.getSession().setMode('ace/mode/json'); - editor.getSession().setUseSoftTabs(true); - editor.getSession().setUseWrapMode(true); - this.editor = editor; - - - if (options.change) { - // register onchange event - editor.on('change', function () { - options.change(); - }); - } - } - else { - // load a plain text textarea - var textarea = document.createElement('textarea'); - textarea.className = 'text'; - textarea.spellcheck = false; - this.content.appendChild(textarea); - this.textarea = textarea; - - if (options.change) { - // register onchange event - if (this.textarea.oninput === null) { - this.textarea.oninput = function () { - options.change(); - } - } - else { - // oninput is undefined. For IE8- - this.textarea.onchange = function () { - options.change(); - } - } - } - } - - // load initial json object or string - if (typeof(json) == 'string') { - this.setText(json); - } - else { - this.set(json); - } -}; - -/** - * Detach the editor from the DOM - * @private - */ -TextEditor.prototype._delete = function () { - if (this.frame && this.container && this.frame.parentNode == this.container) { - this.container.removeChild(this.frame); - } -}; - -/** - * Throw an error. If an error callback is configured in options.error, this - * callback will be invoked. Else, a regular error is thrown. - * @param {Error} err - * @private - */ -TextEditor.prototype._onError = function(err) { - // TODO: onError is deprecated since version 2.2.0. cleanup some day - if (typeof this.onError === 'function') { - util.log('WARNING: JSONEditor.onError is deprecated. ' + - 'Use options.error instead.'); - this.onError(err); - } - - if (this.options && typeof this.options.error === 'function') { - this.options.error(err); - } - else { - throw err; - } -}; - -/** - * Compact the code in the formatter - */ -TextEditor.prototype.compact = function () { - var json = util.parse(this.getText()); - this.setText(JSON.stringify(json)); -}; - -/** - * Format the code in the formatter - */ -TextEditor.prototype.format = function () { - var json = util.parse(this.getText()); - this.setText(JSON.stringify(json, null, this.indentation)); -}; - -/** - * Set focus to the formatter - */ -TextEditor.prototype.focus = function () { - if (this.textarea) { - this.textarea.focus(); - } - if (this.editor) { - this.editor.focus(); - } -}; - -/** - * Resize the formatter - */ -TextEditor.prototype.resize = function () { - if (this.editor) { - var force = false; - this.editor.resize(force); - } -}; - -/** - * Set json data in the formatter - * @param {Object} json - */ -TextEditor.prototype.set = function(json) { - this.setText(JSON.stringify(json, null, this.indentation)); -}; - -/** - * Get json data from the formatter - * @return {Object} json - */ -TextEditor.prototype.get = function() { - return util.parse(this.getText()); -}; - -/** - * Get the text contents of the TextEditor - * @return {String} jsonText - */ -TextEditor.prototype.getText = function() { - if (this.textarea) { - return this.textarea.value; - } - if (this.editor) { - return this.editor.getValue(); - } - return ''; -}; - -/** - * Set the text contents of the TextEditor - * @param {String} jsonText - */ -TextEditor.prototype.setText = function(jsonText) { - if (this.textarea) { - this.textarea.value = jsonText; - } - if (this.editor) { - this.editor.setValue(jsonText, -1); - } -}; - -// register modes at the JSONEditor -JSONEditor.modes.text = { - editor: TextEditor, - data: 'text', - load: TextEditor.prototype.format -}; -JSONEditor.modes.code = { - editor: TextEditor, - data: 'text', - load: TextEditor.prototype.format -}; - -/** - * @constructor Node - * Create a new Node - * @param {TreeEditor} editor - * @param {Object} [params] Can contain parameters: - * {string} field - * {boolean} fieldEditable - * {*} value - * {String} type Can have values 'auto', 'array', - * 'object', or 'string'. - */ -function Node (editor, params) { - /** @type {TreeEditor} */ - this.editor = editor; - this.dom = {}; - this.expanded = false; - - if(params && (params instanceof Object)) { - this.setField(params.field, params.fieldEditable); - this.setValue(params.value, params.type); - } - else { - this.setField(''); - this.setValue(null); - } -}; - -/** - * Set parent node - * @param {Node} parent - */ -Node.prototype.setParent = function(parent) { - this.parent = parent; -}; - -/** - * Set field - * @param {String} field - * @param {boolean} [fieldEditable] - */ -Node.prototype.setField = function(field, fieldEditable) { - this.field = field; - this.fieldEditable = (fieldEditable == true); -}; - -/** - * Get field - * @return {String} - */ -Node.prototype.getField = function() { - if (this.field === undefined) { - this._getDomField(); - } - - return this.field; -}; - -/** - * Set value. Value is a JSON structure or an element String, Boolean, etc. - * @param {*} value - * @param {String} [type] Specify the type of the value. Can be 'auto', - * 'array', 'object', or 'string' - */ -Node.prototype.setValue = function(value, type) { - var childValue, child; - - // first clear all current childs (if any) - var childs = this.childs; - if (childs) { - while (childs.length) { - this.removeChild(childs[0]); - } - } - - // TODO: remove the DOM of this Node - - this.type = this._getType(value); - - // check if type corresponds with the provided type - if (type && type != this.type) { - if (type == 'string' && this.type == 'auto') { - this.type = type; - } - else { - throw new Error('Type mismatch: ' + - 'cannot cast value of type "' + this.type + - ' to the specified type "' + type + '"'); - } - } - - if (this.type == 'array') { - // array - this.childs = []; - for (var i = 0, iMax = value.length; i < iMax; i++) { - childValue = value[i]; - if (childValue !== undefined && !(childValue instanceof Function)) { - // ignore undefined and functions - child = new Node(this.editor, { - 'value': childValue - }); - this.appendChild(child); - } - } - this.value = ''; - } - else if (this.type == 'object') { - // object - this.childs = []; - for (var childField in value) { - if (value.hasOwnProperty(childField)) { - childValue = value[childField]; - if (childValue !== undefined && !(childValue instanceof Function)) { - // ignore undefined and functions - child = new Node(this.editor, { - 'field': childField, - 'value': childValue - }); - this.appendChild(child); - } - } - } - this.value = ''; - } - else { - // value - this.childs = undefined; - this.value = value; - /* TODO - if (typeof(value) == 'string') { - var escValue = JSON.stringify(value); - this.value = escValue.substring(1, escValue.length - 1); - util.log('check', value, this.value); - } - else { - this.value = value; - } - */ - } -}; - -/** - * Get value. Value is a JSON structure - * @return {*} value - */ -Node.prototype.getValue = function() { - //var childs, i, iMax; - - if (this.type == 'array') { - var arr = []; - this.childs.forEach (function (child) { - arr.push(child.getValue()); - }); - return arr; - } - else if (this.type == 'object') { - var obj = {}; - this.childs.forEach (function (child) { - obj[child.getField()] = child.getValue(); - }); - return obj; - } - else { - if (this.value === undefined) { - this._getDomValue(); - } - - return this.value; - } -}; - -/** - * Get the nesting level of this node - * @return {Number} level - */ -Node.prototype.getLevel = function() { - return (this.parent ? this.parent.getLevel() + 1 : 0); -}; - -/** - * Create a clone of a node - * The complete state of a clone is copied, including whether it is expanded or - * not. The DOM elements are not cloned. - * @return {Node} clone - */ -Node.prototype.clone = function() { - var clone = new Node(this.editor); - clone.type = this.type; - clone.field = this.field; - clone.fieldInnerText = this.fieldInnerText; - clone.fieldEditable = this.fieldEditable; - clone.value = this.value; - clone.valueInnerText = this.valueInnerText; - clone.expanded = this.expanded; - - if (this.childs) { - // an object or array - var cloneChilds = []; - this.childs.forEach(function (child) { - var childClone = child.clone(); - childClone.setParent(clone); - cloneChilds.push(childClone); - }); - clone.childs = cloneChilds; - } - else { - // a value - clone.childs = undefined; - } - - return clone; -}; - -/** - * Expand this node and optionally its childs. - * @param {boolean} [recurse] Optional recursion, true by default. When - * true, all childs will be expanded recursively - */ -Node.prototype.expand = function(recurse) { - if (!this.childs) { - return; - } - - // set this node expanded - this.expanded = true; - if (this.dom.expand) { - this.dom.expand.className = 'expanded'; - } - - this.showChilds(); - - if (recurse != false) { - this.childs.forEach(function (child) { - child.expand(recurse); - }); - } -}; - -/** - * Collapse this node and optionally its childs. - * @param {boolean} [recurse] Optional recursion, true by default. When - * true, all childs will be collapsed recursively - */ -Node.prototype.collapse = function(recurse) { - if (!this.childs) { - return; - } - - this.hideChilds(); - - // collapse childs in case of recurse - if (recurse != false) { - this.childs.forEach(function (child) { - child.collapse(recurse); - }); - - } - - // make this node collapsed - if (this.dom.expand) { - this.dom.expand.className = 'collapsed'; - } - this.expanded = false; -}; - -/** - * Recursively show all childs when they are expanded - */ -Node.prototype.showChilds = function() { - var childs = this.childs; - if (!childs) { - return; - } - if (!this.expanded) { - return; - } - - var tr = this.dom.tr; - var table = tr ? tr.parentNode : undefined; - if (table) { - // show row with append button - var append = this.getAppend(); - var nextTr = tr.nextSibling; - if (nextTr) { - table.insertBefore(append, nextTr); - } - else { - table.appendChild(append); - } - - // show childs - this.childs.forEach(function (child) { - table.insertBefore(child.getDom(), append); - child.showChilds(); - }); - } -}; - -/** - * Hide the node with all its childs - */ -Node.prototype.hide = function() { - var tr = this.dom.tr; - var table = tr ? tr.parentNode : undefined; - if (table) { - table.removeChild(tr); - } - this.hideChilds(); -}; - - -/** - * Recursively hide all childs - */ -Node.prototype.hideChilds = function() { - var childs = this.childs; - if (!childs) { - return; - } - if (!this.expanded) { - return; - } - - // hide append row - var append = this.getAppend(); - if (append.parentNode) { - append.parentNode.removeChild(append); - } - - // hide childs - this.childs.forEach(function (child) { - child.hide(); - }); -}; - - -/** - * Add a new child to the node. - * Only applicable when Node value is of type array or object - * @param {Node} node - */ -Node.prototype.appendChild = function(node) { - if (this._hasChilds()) { - // adjust the link to the parent - node.setParent(this); - node.fieldEditable = (this.type == 'object'); - if (this.type == 'array') { - node.index = this.childs.length; - } - this.childs.push(node); - - if (this.expanded) { - // insert into the DOM, before the appendRow - var newTr = node.getDom(); - var appendTr = this.getAppend(); - var table = appendTr ? appendTr.parentNode : undefined; - if (appendTr && table) { - table.insertBefore(newTr, appendTr); - } - - node.showChilds(); - } - - this.updateDom({'updateIndexes': true}); - node.updateDom({'recurse': true}); - } -}; - - -/** - * Move a node from its current parent to this node - * Only applicable when Node value is of type array or object - * @param {Node} node - * @param {Node} beforeNode - */ -Node.prototype.moveBefore = function(node, beforeNode) { - if (this._hasChilds()) { - // create a temporary row, to prevent the scroll position from jumping - // when removing the node - var tbody = (this.dom.tr) ? this.dom.tr.parentNode : undefined; - if (tbody) { - var trTemp = document.createElement('tr'); - trTemp.style.height = tbody.clientHeight + 'px'; - tbody.appendChild(trTemp); - } - - if (node.parent) { - node.parent.removeChild(node); - } - - if (beforeNode instanceof AppendNode) { - this.appendChild(node); - } - else { - this.insertBefore(node, beforeNode); - } - - if (tbody) { - tbody.removeChild(trTemp); - } - } -}; - -/** - * Move a node from its current parent to this node - * Only applicable when Node value is of type array or object. - * If index is out of range, the node will be appended to the end - * @param {Node} node - * @param {Number} index - */ -Node.prototype.moveTo = function (node, index) { - if (node.parent == this) { - // same parent - var currentIndex = this.childs.indexOf(node); - if (currentIndex < index) { - // compensate the index for removal of the node itself - index++; - } - } - - var beforeNode = this.childs[index] || this.append; - this.moveBefore(node, beforeNode); -}; - -/** - * Insert a new child before a given node - * Only applicable when Node value is of type array or object - * @param {Node} node - * @param {Node} beforeNode - */ -Node.prototype.insertBefore = function(node, beforeNode) { - if (this._hasChilds()) { - if (beforeNode == this.append) { - // append to the child nodes - - // adjust the link to the parent - node.setParent(this); - node.fieldEditable = (this.type == 'object'); - this.childs.push(node); - } - else { - // insert before a child node - var index = this.childs.indexOf(beforeNode); - if (index == -1) { - throw new Error('Node not found'); - } - - // adjust the link to the parent - node.setParent(this); - node.fieldEditable = (this.type == 'object'); - this.childs.splice(index, 0, node); - } - - if (this.expanded) { - // insert into the DOM - var newTr = node.getDom(); - var nextTr = beforeNode.getDom(); - var table = nextTr ? nextTr.parentNode : undefined; - if (nextTr && table) { - table.insertBefore(newTr, nextTr); - } - - node.showChilds(); - } - - this.updateDom({'updateIndexes': true}); - node.updateDom({'recurse': true}); - } -}; - -/** - * Insert a new child before a given node - * Only applicable when Node value is of type array or object - * @param {Node} node - * @param {Node} afterNode - */ -Node.prototype.insertAfter = function(node, afterNode) { - if (this._hasChilds()) { - var index = this.childs.indexOf(afterNode); - var beforeNode = this.childs[index + 1]; - if (beforeNode) { - this.insertBefore(node, beforeNode); - } - else { - this.appendChild(node); - } - } -}; - -/** - * Search in this node - * The node will be expanded when the text is found one of its childs, else - * it will be collapsed. Searches are case insensitive. - * @param {String} text - * @return {Node[]} results Array with nodes containing the search text - */ -Node.prototype.search = function(text) { - var results = []; - var index; - var search = text ? text.toLowerCase() : undefined; - - // delete old search data - delete this.searchField; - delete this.searchValue; - - // search in field - if (this.field != undefined) { - var field = String(this.field).toLowerCase(); - index = field.indexOf(search); - if (index != -1) { - this.searchField = true; - results.push({ - 'node': this, - 'elem': 'field' - }); - } - - // update dom - this._updateDomField(); - } - - // search in value - if (this._hasChilds()) { - // array, object - - // search the nodes childs - if (this.childs) { - var childResults = []; - this.childs.forEach(function (child) { - childResults = childResults.concat(child.search(text)); - }); - results = results.concat(childResults); - } - - // update dom - if (search != undefined) { - var recurse = false; - if (childResults.length == 0) { - this.collapse(recurse); - } - else { - this.expand(recurse); - } - } - } - else { - // string, auto - if (this.value != undefined ) { - var value = String(this.value).toLowerCase(); - index = value.indexOf(search); - if (index != -1) { - this.searchValue = true; - results.push({ - 'node': this, - 'elem': 'value' - }); - } - } - - // update dom - this._updateDomValue(); - } - - return results; -}; - -/** - * Move the scroll position such that this node is in the visible area. - * The node will not get the focus - * @param {function(boolean)} [callback] - */ -Node.prototype.scrollTo = function(callback) { - if (!this.dom.tr || !this.dom.tr.parentNode) { - // if the node is not visible, expand its parents - var parent = this.parent; - var recurse = false; - while (parent) { - parent.expand(recurse); - parent = parent.parent; - } - } - - if (this.dom.tr && this.dom.tr.parentNode) { - this.editor.scrollTo(this.dom.tr.offsetTop, callback); - } -}; - - -// stores the element name currently having the focus -Node.focusElement = undefined; - -/** - * Set focus to this node - * @param {String} [elementName] The field name of the element to get the - * focus available values: 'drag', 'menu', - * 'expand', 'field', 'value' (default) - */ -Node.prototype.focus = function(elementName) { - Node.focusElement = elementName; - - if (this.dom.tr && this.dom.tr.parentNode) { - var dom = this.dom; - - switch (elementName) { - case 'drag': - if (dom.drag) { - dom.drag.focus(); - } - else { - dom.menu.focus(); - } - break; - - case 'menu': - dom.menu.focus(); - break; - - case 'expand': - if (this._hasChilds()) { - dom.expand.focus(); - } - else if (dom.field && this.fieldEditable) { - dom.field.focus(); - util.selectContentEditable(dom.field); - } - else if (dom.value && !this._hasChilds()) { - dom.value.focus(); - util.selectContentEditable(dom.value); - } - else { - dom.menu.focus(); - } - break; - - case 'field': - if (dom.field && this.fieldEditable) { - dom.field.focus(); - util.selectContentEditable(dom.field); - } - else if (dom.value && !this._hasChilds()) { - dom.value.focus(); - util.selectContentEditable(dom.value); - } - else if (this._hasChilds()) { - dom.expand.focus(); - } - else { - dom.menu.focus(); - } - break; - - case 'value': - default: - if (dom.value && !this._hasChilds()) { - dom.value.focus(); - util.selectContentEditable(dom.value); - } - else if (dom.field && this.fieldEditable) { - dom.field.focus(); - util.selectContentEditable(dom.field); - } - else if (this._hasChilds()) { - dom.expand.focus(); - } - else { - dom.menu.focus(); - } - break; - } - } -}; - -/** - * Select all text in an editable div after a delay of 0 ms - * @param {Element} editableDiv - */ -Node.select = function(editableDiv) { - setTimeout(function () { - util.selectContentEditable(editableDiv); - }, 0); -}; - -/** - * Update the values from the DOM field and value of this node - */ -Node.prototype.blur = function() { - // retrieve the actual field and value from the DOM. - this._getDomValue(false); - this._getDomField(false); -}; - -/** - * Duplicate given child node - * new structure will be added right before the cloned node - * @param {Node} node the childNode to be duplicated - * @return {Node} clone the clone of the node - * @private - */ -Node.prototype._duplicate = function(node) { - var clone = node.clone(); - - /* TODO: adjust the field name (to prevent equal field names) - if (this.type == 'object') { - } - */ - - this.insertAfter(clone, node); - - return clone; -}; - -/** - * Check if given node is a child. The method will check recursively to find - * this node. - * @param {Node} node - * @return {boolean} containsNode - */ -Node.prototype.containsNode = function(node) { - if (this == node) { - return true; - } - - var childs = this.childs; - if (childs) { - // TODO: use the js5 Array.some() here? - for (var i = 0, iMax = childs.length; i < iMax; i++) { - if (childs[i].containsNode(node)) { - return true; - } - } - } - - return false; -}; - -/** - * Move given node into this node - * @param {Node} node the childNode to be moved - * @param {Node} beforeNode node will be inserted before given - * node. If no beforeNode is given, - * the node is appended at the end - * @private - */ -Node.prototype._move = function(node, beforeNode) { - if (node == beforeNode) { - // nothing to do... - return; - } - - // check if this node is not a child of the node to be moved here - if (node.containsNode(this)) { - throw new Error('Cannot move a field into a child of itself'); - } - - // remove the original node - if (node.parent) { - node.parent.removeChild(node); - } - - // create a clone of the node - var clone = node.clone(); - node.clearDom(); - - // insert or append the node - if (beforeNode) { - this.insertBefore(clone, beforeNode); - } - else { - this.appendChild(clone); - } - - /* TODO: adjust the field name (to prevent equal field names) - if (this.type == 'object') { - } - */ -}; - -/** - * Remove a child from the node. - * Only applicable when Node value is of type array or object - * @param {Node} node The child node to be removed; - * @return {Node | undefined} node The removed node on success, - * else undefined - */ -Node.prototype.removeChild = function(node) { - if (this.childs) { - var index = this.childs.indexOf(node); - - if (index != -1) { - node.hide(); - - // delete old search results - delete node.searchField; - delete node.searchValue; - - var removedNode = this.childs.splice(index, 1)[0]; - - this.updateDom({'updateIndexes': true}); - - return removedNode; - } - } - - return undefined; -}; - -/** - * Remove a child node node from this node - * This method is equal to Node.removeChild, except that _remove firex an - * onChange event. - * @param {Node} node - * @private - */ -Node.prototype._remove = function (node) { - this.removeChild(node); -}; - -/** - * Change the type of the value of this Node - * @param {String} newType - */ -Node.prototype.changeType = function (newType) { - var oldType = this.type; - - if (oldType == newType) { - // type is not changed - return; - } - - if ((newType == 'string' || newType == 'auto') && - (oldType == 'string' || oldType == 'auto')) { - // this is an easy change - this.type = newType; - } - else { - // change from array to object, or from string/auto to object/array - var table = this.dom.tr ? this.dom.tr.parentNode : undefined; - var lastTr; - if (this.expanded) { - lastTr = this.getAppend(); - } - else { - lastTr = this.getDom(); - } - var nextTr = (lastTr && lastTr.parentNode) ? lastTr.nextSibling : undefined; - - // hide current field and all its childs - this.hide(); - this.clearDom(); - - // adjust the field and the value - this.type = newType; - - // adjust childs - if (newType == 'object') { - if (!this.childs) { - this.childs = []; - } - - this.childs.forEach(function (child, index) { - child.clearDom(); - delete child.index; - child.fieldEditable = true; - if (child.field == undefined) { - child.field = ''; - } - }); - - if (oldType == 'string' || oldType == 'auto') { - this.expanded = true; - } - } - else if (newType == 'array') { - if (!this.childs) { - this.childs = []; - } - - this.childs.forEach(function (child, index) { - child.clearDom(); - child.fieldEditable = false; - child.index = index; - }); - - if (oldType == 'string' || oldType == 'auto') { - this.expanded = true; - } - } - else { - this.expanded = false; - } - - // create new DOM - if (table) { - if (nextTr) { - table.insertBefore(this.getDom(), nextTr); - } - else { - table.appendChild(this.getDom()); - } - } - this.showChilds(); - } - - if (newType == 'auto' || newType == 'string') { - // cast value to the correct type - if (newType == 'string') { - this.value = String(this.value); - } - else { - this.value = this._stringCast(String(this.value)); - } - - this.focus(); - } - - this.updateDom({'updateIndexes': true}); -}; - -/** - * Retrieve value from DOM - * @param {boolean} [silent] If true (default), no errors will be thrown in - * case of invalid data - * @private - */ -Node.prototype._getDomValue = function(silent) { - if (this.dom.value && this.type != 'array' && this.type != 'object') { - this.valueInnerText = util.getInnerText(this.dom.value); - } - - if (this.valueInnerText != undefined) { - try { - // retrieve the value - var value; - if (this.type == 'string') { - value = this._unescapeHTML(this.valueInnerText); - } - else { - var str = this._unescapeHTML(this.valueInnerText); - value = this._stringCast(str); - } - if (value !== this.value) { - var oldValue = this.value; - this.value = value; - this.editor._onAction('editValue', { - 'node': this, - 'oldValue': oldValue, - 'newValue': value, - 'oldSelection': this.editor.selection, - 'newSelection': this.editor.getSelection() - }); - } - } - catch (err) { - this.value = undefined; - // TODO: sent an action with the new, invalid value? - if (silent != true) { - throw err; - } - } - } -}; - -/** - * Update dom value: - * - the text color of the value, depending on the type of the value - * - the height of the field, depending on the width - * - background color in case it is empty - * @private - */ -Node.prototype._updateDomValue = function () { - var domValue = this.dom.value; - if (domValue) { - // set text color depending on value type - // TODO: put colors in css - var v = this.value; - var t = (this.type == 'auto') ? util.type(v) : this.type; - var isUrl = (t == 'string' && util.isUrl(v)); - var color = ''; - if (isUrl && !this.editor.mode.edit) { - color = ''; - } - else if (t == 'string') { - color = 'green'; - } - else if (t == 'number') { - color = 'red'; - } - else if (t == 'boolean') { - color = 'darkorange'; - } - else if (this._hasChilds()) { - color = ''; - } - else if (v === null) { - color = '#004ED0'; // blue - } - else { - // invalid value - color = 'black'; - } - domValue.style.color = color; - - // make background color light-gray when empty - var isEmpty = (String(this.value) == '' && this.type != 'array' && this.type != 'object'); - if (isEmpty) { - util.addClassName(domValue, 'empty'); - } - else { - util.removeClassName(domValue, 'empty'); - } - - // underline url - if (isUrl) { - util.addClassName(domValue, 'url'); - } - else { - util.removeClassName(domValue, 'url'); - } - - // update title - if (t == 'array' || t == 'object') { - var count = this.childs ? this.childs.length : 0; - domValue.title = this.type + ' containing ' + count + ' items'; - } - else if (t == 'string' && util.isUrl(v)) { - if (this.editor.mode.edit) { - domValue.title = 'Ctrl+Click or Ctrl+Enter to open url in new window'; - } - } - else { - domValue.title = ''; - } - - // highlight when there is a search result - if (this.searchValueActive) { - util.addClassName(domValue, 'highlight-active'); - } - else { - util.removeClassName(domValue, 'highlight-active'); - } - if (this.searchValue) { - util.addClassName(domValue, 'highlight'); - } - else { - util.removeClassName(domValue, 'highlight'); - } - - // strip formatting from the contents of the editable div - util.stripFormatting(domValue); - } -}; - -/** - * Update dom field: - * - the text color of the field, depending on the text - * - the height of the field, depending on the width - * - background color in case it is empty - * @private - */ -Node.prototype._updateDomField = function () { - var domField = this.dom.field; - if (domField) { - // make backgound color lightgray when empty - var isEmpty = (String(this.field) == '' && this.parent.type != 'array'); - if (isEmpty) { - util.addClassName(domField, 'empty'); - } - else { - util.removeClassName(domField, 'empty'); - } - - // highlight when there is a search result - if (this.searchFieldActive) { - util.addClassName(domField, 'highlight-active'); - } - else { - util.removeClassName(domField, 'highlight-active'); - } - if (this.searchField) { - util.addClassName(domField, 'highlight'); - } - else { - util.removeClassName(domField, 'highlight'); - } - - // strip formatting from the contents of the editable div - util.stripFormatting(domField); - } -}; - -/** - * Retrieve field from DOM - * @param {boolean} [silent] If true (default), no errors will be thrown in - * case of invalid data - * @private - */ -Node.prototype._getDomField = function(silent) { - if (this.dom.field && this.fieldEditable) { - this.fieldInnerText = util.getInnerText(this.dom.field); - } - - if (this.fieldInnerText != undefined) { - try { - var field = this._unescapeHTML(this.fieldInnerText); - - if (field !== this.field) { - var oldField = this.field; - this.field = field; - this.editor._onAction('editField', { - 'node': this, - 'oldValue': oldField, - 'newValue': field, - 'oldSelection': this.editor.selection, - 'newSelection': this.editor.getSelection() - }); - } - } - catch (err) { - this.field = undefined; - // TODO: sent an action here, with the new, invalid value? - if (silent != true) { - throw err; - } - } - } -}; - -/** - * Clear the dom of the node - */ -Node.prototype.clearDom = function() { - // TODO: hide the node first? - //this.hide(); - // TODO: recursively clear dom? - - this.dom = {}; -}; - -/** - * Get the HTML DOM TR element of the node. - * The dom will be generated when not yet created - * @return {Element} tr HTML DOM TR Element - */ -Node.prototype.getDom = function() { - var dom = this.dom; - if (dom.tr) { - return dom.tr; - } - - // create row - dom.tr = document.createElement('tr'); - dom.tr.node = this; - - if (this.editor.mode.edit) { - // create draggable area - var tdDrag = document.createElement('td'); - if (this.parent) { - var domDrag = document.createElement('button'); - dom.drag = domDrag; - domDrag.className = 'dragarea'; - domDrag.title = 'Drag to move this field (Alt+Shift+Arrows)'; - tdDrag.appendChild(domDrag); - } - dom.tr.appendChild(tdDrag); - - // create context menu - var tdMenu = document.createElement('td'); - var menu = document.createElement('button'); - dom.menu = menu; - menu.className = 'contextmenu'; - menu.title = 'Click to open the actions menu (Ctrl+M)'; - tdMenu.appendChild(dom.menu); - dom.tr.appendChild(tdMenu); - } - - // create tree and field - var tdField = document.createElement('td'); - dom.tr.appendChild(tdField); - dom.tree = this._createDomTree(); - tdField.appendChild(dom.tree); - - this.updateDom({'updateIndexes': true}); - - return dom.tr; -}; - -/** - * DragStart event, fired on mousedown on the dragarea at the left side of a Node - * @param {Event} event - * @private - */ -Node.prototype._onDragStart = function (event) { - var node = this; - if (!this.mousemove) { - this.mousemove = util.addEventListener(document, 'mousemove', - function (event) { - node._onDrag(event); - }); - } - - if (!this.mouseup) { - this.mouseup = util.addEventListener(document, 'mouseup', - function (event ) { - node._onDragEnd(event); - }); - } - - this.editor.highlighter.lock(); - this.drag = { - 'oldCursor': document.body.style.cursor, - 'startParent': this.parent, - 'startIndex': this.parent.childs.indexOf(this), - 'mouseX': event.pageX, - 'level': this.getLevel() - }; - document.body.style.cursor = 'move'; - - event.preventDefault(); -}; - -/** - * Drag event, fired when moving the mouse while dragging a Node - * @param {Event} event - * @private - */ -Node.prototype._onDrag = function (event) { - // TODO: this method has grown too large. Split it in a number of methods - var mouseY = event.pageY; - var mouseX = event.pageX; - - var trThis, trPrev, trNext, trFirst, trLast, trRoot; - var nodePrev, nodeNext; - var topThis, topPrev, topFirst, heightThis, bottomNext, heightNext; - var moved = false; - - // TODO: add an ESC option, which resets to the original position - - // move up/down - trThis = this.dom.tr; - topThis = util.getAbsoluteTop(trThis); - heightThis = trThis.offsetHeight; - if (mouseY < topThis) { - // move up - trPrev = trThis; - do { - trPrev = trPrev.previousSibling; - nodePrev = Node.getNodeFromTarget(trPrev); - topPrev = trPrev ? util.getAbsoluteTop(trPrev) : 0; - } - while (trPrev && mouseY < topPrev); - - if (nodePrev && !nodePrev.parent) { - nodePrev = undefined; - } - - if (!nodePrev) { - // move to the first node - trRoot = trThis.parentNode.firstChild; - trPrev = trRoot ? trRoot.nextSibling : undefined; - nodePrev = Node.getNodeFromTarget(trPrev); - if (nodePrev == this) { - nodePrev = undefined; - } - } - - if (nodePrev) { - // check if mouseY is really inside the found node - trPrev = nodePrev.dom.tr; - topPrev = trPrev ? util.getAbsoluteTop(trPrev) : 0; - if (mouseY > topPrev + heightThis) { - nodePrev = undefined; - } - } - - if (nodePrev) { - nodePrev.parent.moveBefore(this, nodePrev); - moved = true; - } - } - else { - // move down - trLast = (this.expanded && this.append) ? this.append.getDom() : this.dom.tr; - trFirst = trLast ? trLast.nextSibling : undefined; - if (trFirst) { - topFirst = util.getAbsoluteTop(trFirst); - trNext = trFirst; - do { - nodeNext = Node.getNodeFromTarget(trNext); - if (trNext) { - bottomNext = trNext.nextSibling ? - util.getAbsoluteTop(trNext.nextSibling) : 0; - heightNext = trNext ? (bottomNext - topFirst) : 0; - - if (nodeNext.parent.childs.length == 1 && nodeNext.parent.childs[0] == this) { - // We are about to remove the last child of this parent, - // which will make the parents appendNode visible. - topThis += 24 - 1; - // TODO: dangerous to suppose the height of the appendNode a constant of 24-1 px. - } - } - - trNext = trNext.nextSibling; - } - while (trNext && mouseY > topThis + heightNext); - - if (nodeNext && nodeNext.parent) { - // calculate the desired level - var diffX = (mouseX - this.drag.mouseX); - var diffLevel = Math.round(diffX / 24 / 2); - var level = this.drag.level + diffLevel; // desired level - var levelNext = nodeNext.getLevel(); // level to be - - // find the best fitting level (move upwards over the append nodes) - trPrev = nodeNext.dom.tr.previousSibling; - while (levelNext < level && trPrev) { - nodePrev = Node.getNodeFromTarget(trPrev); - if (nodePrev == this || nodePrev._isChildOf(this)) { - // neglect itself and its childs - } - else if (nodePrev instanceof AppendNode) { - var childs = nodePrev.parent.childs; - if (childs.length > 1 || - (childs.length == 1 && childs[0] != this)) { - // non-visible append node of a list of childs - // consisting of not only this node (else the - // append node will change into a visible "empty" - // text when removing this node). - nodeNext = Node.getNodeFromTarget(trPrev); - levelNext = nodeNext.getLevel(); - } - else { - break; - } - } - else { - break; - } - - trPrev = trPrev.previousSibling; - } - - // move the node when its position is changed - if (trLast.nextSibling != nodeNext.dom.tr) { - nodeNext.parent.moveBefore(this, nodeNext); - moved = true; - } - } - } - } - - if (moved) { - // update the dragging parameters when moved - this.drag.mouseX = mouseX; - this.drag.level = this.getLevel(); - } - - // auto scroll when hovering around the top of the editor - this.editor.startAutoScroll(mouseY); - - event.preventDefault(); -}; - -/** - * Drag event, fired on mouseup after having dragged a node - * @param {Event} event - * @private - */ -Node.prototype._onDragEnd = function (event) { - var params = { - 'node': this, - 'startParent': this.drag.startParent, - 'startIndex': this.drag.startIndex, - 'endParent': this.parent, - 'endIndex': this.parent.childs.indexOf(this) - }; - if ((params.startParent != params.endParent) || - (params.startIndex != params.endIndex)) { - // only register this action if the node is actually moved to another place - this.editor._onAction('moveNode', params); - } - - document.body.style.cursor = this.drag.oldCursor; - this.editor.highlighter.unlock(); - delete this.drag; - - if (this.mousemove) { - util.removeEventListener(document, 'mousemove', this.mousemove); - delete this.mousemove;} - if (this.mouseup) { - util.removeEventListener(document, 'mouseup', this.mouseup); - delete this.mouseup; - } - - // Stop any running auto scroll - this.editor.stopAutoScroll(); - - event.preventDefault(); -}; - -/** - * Test if this node is a child of an other node - * @param {Node} node - * @return {boolean} isChild - * @private - */ -Node.prototype._isChildOf = function (node) { - var n = this.parent; - while (n) { - if (n == node) { - return true; - } - n = n.parent; - } - - return false; -}; - -/** - * Create an editable field - * @return {Element} domField - * @private - */ -Node.prototype._createDomField = function () { - return document.createElement('div'); -}; - -/** - * Set highlighting for this node and all its childs. - * Only applied to the currently visible (expanded childs) - * @param {boolean} highlight - */ -Node.prototype.setHighlight = function (highlight) { - if (this.dom.tr) { - this.dom.tr.className = (highlight ? 'highlight' : ''); - - if (this.append) { - this.append.setHighlight(highlight); - } - - if (this.childs) { - this.childs.forEach(function (child) { - child.setHighlight(highlight); - }); - } - } -}; - -/** - * Update the value of the node. Only primitive types are allowed, no Object - * or Array is allowed. - * @param {String | Number | Boolean | null} value - */ -Node.prototype.updateValue = function (value) { - this.value = value; - this.updateDom(); -}; - -/** - * Update the field of the node. - * @param {String} field - */ -Node.prototype.updateField = function (field) { - this.field = field; - this.updateDom(); -}; - -/** - * Update the HTML DOM, optionally recursing through the childs - * @param {Object} [options] Available parameters: - * {boolean} [recurse] If true, the - * DOM of the childs will be updated recursively. - * False by default. - * {boolean} [updateIndexes] If true, the childs - * indexes of the node will be updated too. False by - * default. - */ -Node.prototype.updateDom = function (options) { - // update level indentation - var domTree = this.dom.tree; - if (domTree) { - domTree.style.marginLeft = this.getLevel() * 24 + 'px'; - } - - // update field - var domField = this.dom.field; - if (domField) { - if (this.fieldEditable == true) { - // parent is an object - domField.contentEditable = this.editor.mode.edit; - domField.spellcheck = false; - domField.className = 'field'; - } - else { - // parent is an array this is the root node - domField.className = 'readonly'; - } - - var field; - if (this.index != undefined) { - field = this.index; - } - else if (this.field != undefined) { - field = this.field; - } - else if (this._hasChilds()) { - field = this.type; - } - else { - field = ''; - } - domField.innerHTML = this._escapeHTML(field); - } - - // update value - var domValue = this.dom.value; - if (domValue) { - var count = this.childs ? this.childs.length : 0; - if (this.type == 'array') { - domValue.innerHTML = '[' + count + ']'; - } - else if (this.type == 'object') { - domValue.innerHTML = '{' + count + '}'; - } - else { - domValue.innerHTML = this._escapeHTML(this.value); - } - } - - // update field and value - this._updateDomField(); - this._updateDomValue(); - - // update childs indexes - if (options && options.updateIndexes == true) { - // updateIndexes is true or undefined - this._updateDomIndexes(); - } - - if (options && options.recurse == true) { - // recurse is true or undefined. update childs recursively - if (this.childs) { - this.childs.forEach(function (child) { - child.updateDom(options); - }); - } - } - - // update row with append button - if (this.append) { - this.append.updateDom(); - } -}; - -/** - * Update the DOM of the childs of a node: update indexes and undefined field - * names. - * Only applicable when structure is an array or object - * @private - */ -Node.prototype._updateDomIndexes = function () { - var domValue = this.dom.value; - var childs = this.childs; - if (domValue && childs) { - if (this.type == 'array') { - childs.forEach(function (child, index) { - child.index = index; - var childField = child.dom.field; - if (childField) { - childField.innerHTML = index; - } - }); - } - else if (this.type == 'object') { - childs.forEach(function (child) { - if (child.index != undefined) { - delete child.index; - - if (child.field == undefined) { - child.field = ''; - } - } - }); - } - } -}; - -/** - * Create an editable value - * @private - */ -Node.prototype._createDomValue = function () { - var domValue; - - if (this.type == 'array') { - domValue = document.createElement('div'); - domValue.className = 'readonly'; - domValue.innerHTML = '[...]'; - } - else if (this.type == 'object') { - domValue = document.createElement('div'); - domValue.className = 'readonly'; - domValue.innerHTML = '{...}'; - } - else { - if (!this.editor.mode.edit && util.isUrl(this.value)) { - // create a link in case of read-only editor and value containing an url - domValue = document.createElement('a'); - domValue.className = 'value'; - domValue.href = this.value; - domValue.target = '_blank'; - domValue.innerHTML = this._escapeHTML(this.value); - } - else { - // create and editable or read-only div - domValue = document.createElement('div'); - domValue.contentEditable = !this.editor.mode.view; - domValue.spellcheck = false; - domValue.className = 'value'; - domValue.innerHTML = this._escapeHTML(this.value); - } - } - - return domValue; -}; - -/** - * Create an expand/collapse button - * @return {Element} expand - * @private - */ -Node.prototype._createDomExpandButton = function () { - // create expand button - var expand = document.createElement('button'); - if (this._hasChilds()) { - expand.className = this.expanded ? 'expanded' : 'collapsed'; - expand.title = - 'Click to expand/collapse this field (Ctrl+E). \n' + - 'Ctrl+Click to expand/collapse including all childs.'; - } - else { - expand.className = 'invisible'; - expand.title = ''; - } - - return expand; -}; - - -/** - * Create a DOM tree element, containing the expand/collapse button - * @return {Element} domTree - * @private - */ -Node.prototype._createDomTree = function () { - var dom = this.dom; - var domTree = document.createElement('table'); - var tbody = document.createElement('tbody'); - domTree.style.borderCollapse = 'collapse'; // TODO: put in css - domTree.className = 'values'; - domTree.appendChild(tbody); - var tr = document.createElement('tr'); - tbody.appendChild(tr); - - // create expand button - var tdExpand = document.createElement('td'); - tdExpand.className = 'tree'; - tr.appendChild(tdExpand); - dom.expand = this._createDomExpandButton(); - tdExpand.appendChild(dom.expand); - dom.tdExpand = tdExpand; - - // create the field - var tdField = document.createElement('td'); - tdField.className = 'tree'; - tr.appendChild(tdField); - dom.field = this._createDomField(); - tdField.appendChild(dom.field); - dom.tdField = tdField; - - // create a separator - var tdSeparator = document.createElement('td'); - tdSeparator.className = 'tree'; - tr.appendChild(tdSeparator); - if (this.type != 'object' && this.type != 'array') { - tdSeparator.appendChild(document.createTextNode(':')); - tdSeparator.className = 'separator'; - } - dom.tdSeparator = tdSeparator; - - // create the value - var tdValue = document.createElement('td'); - tdValue.className = 'tree'; - tr.appendChild(tdValue); - dom.value = this._createDomValue(); - tdValue.appendChild(dom.value); - dom.tdValue = tdValue; - - return domTree; -}; - -/** - * Handle an event. The event is catched centrally by the editor - * @param {Event} event - */ -Node.prototype.onEvent = function (event) { - var type = event.type, - target = event.target || event.srcElement, - dom = this.dom, - node = this, - focusNode, - expandable = this._hasChilds(); - - // check if mouse is on menu or on dragarea. - // If so, highlight current row and its childs - if (target == dom.drag || target == dom.menu) { - if (type == 'mouseover') { - this.editor.highlighter.highlight(this); - } - else if (type == 'mouseout') { - this.editor.highlighter.unhighlight(); - } - } - - // drag events - if (type == 'mousedown' && target == dom.drag) { - this._onDragStart(event); - } - - // context menu events - if (type == 'click' && target == dom.menu) { - var highlighter = node.editor.highlighter; - highlighter.highlight(node); - highlighter.lock(); - util.addClassName(dom.menu, 'selected'); - this.showContextMenu(dom.menu, function () { - util.removeClassName(dom.menu, 'selected'); - highlighter.unlock(); - highlighter.unhighlight(); - }); - } - - // expand events - if (type == 'click' && target == dom.expand) { - if (expandable) { - var recurse = event.ctrlKey; // with ctrl-key, expand/collapse all - this._onExpand(recurse); - } - } - - // value events - var domValue = dom.value; - if (target == domValue) { - //noinspection FallthroughInSwitchStatementJS - switch (type) { - case 'focus': - focusNode = this; - break; - - case 'blur': - case 'change': - this._getDomValue(true); - this._updateDomValue(); - if (this.value) { - domValue.innerHTML = this._escapeHTML(this.value); - } - break; - - case 'input': - this._getDomValue(true); - this._updateDomValue(); - break; - - case 'keydown': - case 'mousedown': - this.editor.selection = this.editor.getSelection(); - break; - - case 'click': - if (event.ctrlKey && this.editor.mode.edit) { - if (util.isUrl(this.value)) { - window.open(this.value, '_blank'); - } - } - break; - - case 'keyup': - this._getDomValue(true); - this._updateDomValue(); - break; - - case 'cut': - case 'paste': - setTimeout(function () { - node._getDomValue(true); - node._updateDomValue(); - }, 1); - break; - } - } - - // field events - var domField = dom.field; - if (target == domField) { - switch (type) { - case 'focus': - focusNode = this; - break; - - case 'blur': - case 'change': - this._getDomField(true); - this._updateDomField(); - if (this.field) { - domField.innerHTML = this._escapeHTML(this.field); - } - break; - - case 'input': - this._getDomField(true); - this._updateDomField(); - break; - - case 'keydown': - case 'mousedown': - this.editor.selection = this.editor.getSelection(); - break; - - case 'keyup': - this._getDomField(true); - this._updateDomField(); - break; - - case 'cut': - case 'paste': - setTimeout(function () { - node._getDomField(true); - node._updateDomField(); - }, 1); - break; - } - } - - // focus - // when clicked in whitespace left or right from the field or value, set focus - var domTree = dom.tree; - if (target == domTree.parentNode) { - switch (type) { - case 'click': - var left = (event.offsetX != undefined) ? - (event.offsetX < (this.getLevel() + 1) * 24) : - (event.pageX < util.getAbsoluteLeft(dom.tdSeparator));// for FF - if (left || expandable) { - // node is expandable when it is an object or array - if (domField) { - util.setEndOfContentEditable(domField); - domField.focus(); - } - } - else { - if (domValue) { - util.setEndOfContentEditable(domValue); - domValue.focus(); - } - } - break; - } - } - if ((target == dom.tdExpand && !expandable) || target == dom.tdField || - target == dom.tdSeparator) { - switch (type) { - case 'click': - if (domField) { - util.setEndOfContentEditable(domField); - domField.focus(); - } - break; - } - } - - if (type == 'keydown') { - this.onKeyDown(event); - } -}; - -/** - * Key down event handler - * @param {Event} event - */ -Node.prototype.onKeyDown = function (event) { - var keynum = event.which || event.keyCode; - var target = event.target || event.srcElement; - var ctrlKey = event.ctrlKey; - var shiftKey = event.shiftKey; - var altKey = event.altKey; - var handled = false; - var prevNode, nextNode, nextDom, nextDom2; - - // util.log(ctrlKey, keynum, event.charCode); // TODO: cleanup - if (keynum == 13) { // Enter - if (target == this.dom.value) { - if (!this.editor.mode.edit || event.ctrlKey) { - if (util.isUrl(this.value)) { - window.open(this.value, '_blank'); - handled = true; - } - } - } - else if (target == this.dom.expand) { - var expandable = this._hasChilds(); - if (expandable) { - var recurse = event.ctrlKey; // with ctrl-key, expand/collapse all - this._onExpand(recurse); - target.focus(); - handled = true; - } - } - } - else if (keynum == 68) { // D - if (ctrlKey) { // Ctrl+D - this._onDuplicate(); - handled = true; - } - } - else if (keynum == 69) { // E - if (ctrlKey) { // Ctrl+E and Ctrl+Shift+E - this._onExpand(shiftKey); // recurse = shiftKey - target.focus(); // TODO: should restore focus in case of recursing expand (which takes DOM offline) - handled = true; - } - } - else if (keynum == 77) { // M - if (ctrlKey) { // Ctrl+M - this.showContextMenu(target); - handled = true; - } - } - else if (keynum == 46) { // Del - if (ctrlKey) { // Ctrl+Del - this._onRemove(); - handled = true; - } - } - else if (keynum == 45) { // Ins - if (ctrlKey && !shiftKey) { // Ctrl+Ins - this._onInsertBefore(); - handled = true; - } - else if (ctrlKey && shiftKey) { // Ctrl+Shift+Ins - this._onInsertAfter(); - handled = true; - } - } - else if (keynum == 35) { // End - if (altKey) { // Alt+End - // find the last node - var lastNode = this._lastNode(); - if (lastNode) { - lastNode.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - } - else if (keynum == 36) { // Home - if (altKey) { // Alt+Home - // find the first node - var firstNode = this._firstNode(); - if (firstNode) { - firstNode.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - } - else if (keynum == 37) { // Arrow Left - if (altKey && !shiftKey) { // Alt + Arrow Left - // move to left element - var prevElement = this._previousElement(target); - if (prevElement) { - this.focus(this._getElementName(prevElement)); - } - handled = true; - } - else if (altKey && shiftKey) { // Alt + Shift Arrow left - if (this.expanded) { - var appendDom = this.getAppend(); - nextDom = appendDom ? appendDom.nextSibling : undefined; - } - else { - var dom = this.getDom(); - nextDom = dom.nextSibling; - } - if (nextDom) { - nextNode = Node.getNodeFromTarget(nextDom); - nextDom2 = nextDom.nextSibling; - nextNode2 = Node.getNodeFromTarget(nextDom2); - if (nextNode && nextNode instanceof AppendNode && - !(this.parent.childs.length == 1) && - nextNode2 && nextNode2.parent) { - nextNode2.parent.moveBefore(this, nextNode2); - this.focus(Node.focusElement || this._getElementName(target)); - } - } - } - } - else if (keynum == 38) { // Arrow Up - if (altKey && !shiftKey) { // Alt + Arrow Up - // find the previous node - prevNode = this._previousNode(); - if (prevNode) { - prevNode.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - else if (altKey && shiftKey) { // Alt + Shift + Arrow Up - // find the previous node - prevNode = this._previousNode(); - if (prevNode && prevNode.parent) { - prevNode.parent.moveBefore(this, prevNode); - this.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - } - else if (keynum == 39) { // Arrow Right - if (altKey && !shiftKey) { // Alt + Arrow Right - // move to right element - var nextElement = this._nextElement(target); - if (nextElement) { - this.focus(this._getElementName(nextElement)); - } - handled = true; - } - else if (altKey && shiftKey) { // Alt + Shift Arrow Right - dom = this.getDom(); - var prevDom = dom.previousSibling; - if (prevDom) { - prevNode = Node.getNodeFromTarget(prevDom); - if (prevNode && prevNode.parent && - (prevNode instanceof AppendNode) - && !prevNode.isVisible()) { - prevNode.parent.moveBefore(this, prevNode); - this.focus(Node.focusElement || this._getElementName(target)); - } - } - } - } - else if (keynum == 40) { // Arrow Down - if (altKey && !shiftKey) { // Alt + Arrow Down - // find the next node - nextNode = this._nextNode(); - if (nextNode) { - nextNode.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - else if (altKey && shiftKey) { // Alt + Shift + Arrow Down - // find the 2nd next node and move before that one - if (this.expanded) { - nextNode = this.append ? this.append._nextNode() : undefined; - } - else { - nextNode = this._nextNode(); - } - nextDom = nextNode ? nextNode.getDom() : undefined; - if (this.parent.childs.length == 1) { - nextDom2 = nextDom; - } - else { - nextDom2 = nextDom ? nextDom.nextSibling : undefined; - } - var nextNode2 = Node.getNodeFromTarget(nextDom2); - if (nextNode2 && nextNode2.parent) { - nextNode2.parent.moveBefore(this, nextNode2); - this.focus(Node.focusElement || this._getElementName(target)); - } - handled = true; - } - } - - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } -}; - -/** - * Handle the expand event, when clicked on the expand button - * @param {boolean} recurse If true, child nodes will be expanded too - * @private - */ -Node.prototype._onExpand = function (recurse) { - if (recurse) { - // Take the table offline - var table = this.dom.tr.parentNode; // TODO: not nice to access the main table like this - var frame = table.parentNode; - var scrollTop = frame.scrollTop; - frame.removeChild(table); - } - - if (this.expanded) { - this.collapse(recurse); - } - else { - this.expand(recurse); - } - - if (recurse) { - // Put the table online again - frame.appendChild(table); - frame.scrollTop = scrollTop; - } -}; - -/** - * Remove this node - * @private - */ -Node.prototype._onRemove = function() { - this.editor.highlighter.unhighlight(); - var childs = this.parent.childs; - var index = childs.indexOf(this); - - // adjust the focus - var oldSelection = this.editor.getSelection(); - if (childs[index + 1]) { - childs[index + 1].focus(); - } - else if (childs[index - 1]) { - childs[index - 1].focus(); - } - else { - this.parent.focus(); - } - var newSelection = this.editor.getSelection(); - - // remove the node - this.parent._remove(this); - - // store history action - this.editor._onAction('removeNode', { - 'node': this, - 'parent': this.parent, - 'index': index, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); -}; - -/** - * Duplicate this node - * @private - */ -Node.prototype._onDuplicate = function() { - var oldSelection = this.editor.getSelection(); - var clone = this.parent._duplicate(this); - clone.focus(); - var newSelection = this.editor.getSelection(); - - this.editor._onAction('duplicateNode', { - 'node': this, - 'clone': clone, - 'parent': this.parent, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); -}; - -/** - * Handle insert before event - * @param {String} [field] - * @param {*} [value] - * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' - * @private - */ -Node.prototype._onInsertBefore = function (field, value, type) { - var oldSelection = this.editor.getSelection(); - - var newNode = new Node(this.editor, { - 'field': (field != undefined) ? field : '', - 'value': (value != undefined) ? value : '', - 'type': type - }); - newNode.expand(true); - this.parent.insertBefore(newNode, this); - this.editor.highlighter.unhighlight(); - newNode.focus('field'); - var newSelection = this.editor.getSelection(); - - this.editor._onAction('insertBeforeNode', { - 'node': newNode, - 'beforeNode': this, - 'parent': this.parent, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); -}; - -/** - * Handle insert after event - * @param {String} [field] - * @param {*} [value] - * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' - * @private - */ -Node.prototype._onInsertAfter = function (field, value, type) { - var oldSelection = this.editor.getSelection(); - - var newNode = new Node(this.editor, { - 'field': (field != undefined) ? field : '', - 'value': (value != undefined) ? value : '', - 'type': type - }); - newNode.expand(true); - this.parent.insertAfter(newNode, this); - this.editor.highlighter.unhighlight(); - newNode.focus('field'); - var newSelection = this.editor.getSelection(); - - this.editor._onAction('insertAfterNode', { - 'node': newNode, - 'afterNode': this, - 'parent': this.parent, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); -}; - -/** - * Handle append event - * @param {String} [field] - * @param {*} [value] - * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' - * @private - */ -Node.prototype._onAppend = function (field, value, type) { - var oldSelection = this.editor.getSelection(); - - var newNode = new Node(this.editor, { - 'field': (field != undefined) ? field : '', - 'value': (value != undefined) ? value : '', - 'type': type - }); - newNode.expand(true); - this.parent.appendChild(newNode); - this.editor.highlighter.unhighlight(); - newNode.focus('field'); - var newSelection = this.editor.getSelection(); - - this.editor._onAction('appendNode', { - 'node': newNode, - 'parent': this.parent, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); -}; - -/** - * Change the type of the node's value - * @param {String} newType - * @private - */ -Node.prototype._onChangeType = function (newType) { - var oldType = this.type; - if (newType != oldType) { - var oldSelection = this.editor.getSelection(); - this.changeType(newType); - var newSelection = this.editor.getSelection(); - - this.editor._onAction('changeType', { - 'node': this, - 'oldType': oldType, - 'newType': newType, - 'oldSelection': oldSelection, - 'newSelection': newSelection - }); - } -}; - -/** - * Sort the childs of the node. Only applicable when the node has type 'object' - * or 'array'. - * @param {String} direction Sorting direction. Available values: "asc", "desc" - * @private - */ -Node.prototype._onSort = function (direction) { - if (this._hasChilds()) { - var order = (direction == 'desc') ? -1 : 1; - var prop = (this.type == 'array') ? 'value': 'field'; - this.hideChilds(); - - var oldChilds = this.childs; - var oldSort = this.sort; - - // copy the array (the old one will be kept for an undo action - this.childs = this.childs.concat(); - - // sort the arrays - this.childs.sort(function (a, b) { - if (a[prop] > b[prop]) return order; - if (a[prop] < b[prop]) return -order; - return 0; - }); - this.sort = (order == 1) ? 'asc' : 'desc'; - - this.editor._onAction('sort', { - 'node': this, - 'oldChilds': oldChilds, - 'oldSort': oldSort, - 'newChilds': this.childs, - 'newSort': this.sort - }); - - this.showChilds(); - } -}; - -/** - * Create a table row with an append button. - * @return {HTMLElement | undefined} buttonAppend or undefined when inapplicable - */ -Node.prototype.getAppend = function () { - if (!this.append) { - this.append = new AppendNode(this.editor); - this.append.setParent(this); - } - return this.append.getDom(); -}; - -/** - * Find the node from an event target - * @param {Node} target - * @return {Node | undefined} node or undefined when not found - * @static - */ -Node.getNodeFromTarget = function (target) { - while (target) { - if (target.node) { - return target.node; - } - target = target.parentNode; - } - - return undefined; -}; - -/** - * Get the previously rendered node - * @return {Node | null} previousNode - * @private - */ -Node.prototype._previousNode = function () { - var prevNode = null; - var dom = this.getDom(); - if (dom && dom.parentNode) { - // find the previous field - var prevDom = dom; - do { - prevDom = prevDom.previousSibling; - prevNode = Node.getNodeFromTarget(prevDom); - } - while (prevDom && (prevNode instanceof AppendNode && !prevNode.isVisible())); - } - return prevNode; -}; - -/** - * Get the next rendered node - * @return {Node | null} nextNode - * @private - */ -Node.prototype._nextNode = function () { - var nextNode = null; - var dom = this.getDom(); - if (dom && dom.parentNode) { - // find the previous field - var nextDom = dom; - do { - nextDom = nextDom.nextSibling; - nextNode = Node.getNodeFromTarget(nextDom); - } - while (nextDom && (nextNode instanceof AppendNode && !nextNode.isVisible())); - } - - return nextNode; -}; - -/** - * Get the first rendered node - * @return {Node | null} firstNode - * @private - */ -Node.prototype._firstNode = function () { - var firstNode = null; - var dom = this.getDom(); - if (dom && dom.parentNode) { - var firstDom = dom.parentNode.firstChild; - firstNode = Node.getNodeFromTarget(firstDom); - } - - return firstNode; -}; - -/** - * Get the last rendered node - * @return {Node | null} lastNode - * @private - */ -Node.prototype._lastNode = function () { - var lastNode = null; - var dom = this.getDom(); - if (dom && dom.parentNode) { - var lastDom = dom.parentNode.lastChild; - lastNode = Node.getNodeFromTarget(lastDom); - while (lastDom && (lastNode instanceof AppendNode && !lastNode.isVisible())) { - lastDom = lastDom.previousSibling; - lastNode = Node.getNodeFromTarget(lastDom); - } - } - return lastNode; -}; - -/** - * Get the next element which can have focus. - * @param {Element} elem - * @return {Element | null} nextElem - * @private - */ -Node.prototype._previousElement = function (elem) { - var dom = this.dom; - // noinspection FallthroughInSwitchStatementJS - switch (elem) { - case dom.value: - if (this.fieldEditable) { - return dom.field; - } - // intentional fall through - case dom.field: - if (this._hasChilds()) { - return dom.expand; - } - // intentional fall through - case dom.expand: - return dom.menu; - case dom.menu: - if (dom.drag) { - return dom.drag; - } - // intentional fall through - default: - return null; - } -}; - -/** - * Get the next element which can have focus. - * @param {Element} elem - * @return {Element | null} nextElem - * @private - */ -Node.prototype._nextElement = function (elem) { - var dom = this.dom; - // noinspection FallthroughInSwitchStatementJS - switch (elem) { - case dom.drag: - return dom.menu; - case dom.menu: - if (this._hasChilds()) { - return dom.expand; - } - // intentional fall through - case dom.expand: - if (this.fieldEditable) { - return dom.field; - } - // intentional fall through - case dom.field: - if (!this._hasChilds()) { - return dom.value; - } - default: - return null; - } -}; - -/** - * Get the dom name of given element. returns null if not found. - * For example when element == dom.field, "field" is returned. - * @param {Element} element - * @return {String | null} elementName Available elements with name: 'drag', - * 'menu', 'expand', 'field', 'value' - * @private - */ -Node.prototype._getElementName = function (element) { - var dom = this.dom; - for (var name in dom) { - if (dom.hasOwnProperty(name)) { - if (dom[name] == element) { - return name; - } - } - } - return null; -}; - -/** - * Test if this node has childs. This is the case when the node is an object - * or array. - * @return {boolean} hasChilds - * @private - */ -Node.prototype._hasChilds = function () { - return this.type == 'array' || this.type == 'object'; -}; - -// titles with explanation for the different types -Node.TYPE_TITLES = { - 'auto': 'Field type "auto". ' + - 'The field type is automatically determined from the value ' + - 'and can be a string, number, boolean, or null.', - 'object': 'Field type "object". ' + - 'An object contains an unordered set of key/value pairs.', - 'array': 'Field type "array". ' + - 'An array contains an ordered collection of values.', - 'string': 'Field type "string". ' + - 'Field type is not determined from the value, ' + - 'but always returned as string.' -}; - -/** - * Show a contextmenu for this node - * @param {HTMLElement} anchor Anchor element to attache the context menu to. - * @param {function} [onClose] Callback method called when the context menu - * is being closed. - */ -Node.prototype.showContextMenu = function (anchor, onClose) { - var node = this; - var titles = Node.TYPE_TITLES; - var items = []; - - items.push({ - 'text': 'Type', - 'title': 'Change the type of this field', - 'className': 'type-' + this.type, - 'submenu': [ - { - 'text': 'Auto', - 'className': 'type-auto' + - (this.type == 'auto' ? ' selected' : ''), - 'title': titles.auto, - 'click': function () { - node._onChangeType('auto'); - } - }, - { - 'text': 'Array', - 'className': 'type-array' + - (this.type == 'array' ? ' selected' : ''), - 'title': titles.array, - 'click': function () { - node._onChangeType('array'); - } - }, - { - 'text': 'Object', - 'className': 'type-object' + - (this.type == 'object' ? ' selected' : ''), - 'title': titles.object, - 'click': function () { - node._onChangeType('object'); - } - }, - { - 'text': 'String', - 'className': 'type-string' + - (this.type == 'string' ? ' selected' : ''), - 'title': titles.string, - 'click': function () { - node._onChangeType('string'); - } - } - ] - }); - - if (this._hasChilds()) { - var direction = ((this.sort == 'asc') ? 'desc': 'asc'); - items.push({ - 'text': 'Sort', - 'title': 'Sort the childs of this ' + this.type, - 'className': 'sort-' + direction, - 'click': function () { - node._onSort(direction); - }, - 'submenu': [ - { - 'text': 'Ascending', - 'className': 'sort-asc', - 'title': 'Sort the childs of this ' + this.type + ' in ascending order', - 'click': function () { - node._onSort('asc'); - } - }, - { - 'text': 'Descending', - 'className': 'sort-desc', - 'title': 'Sort the childs of this ' + this.type +' in descending order', - 'click': function () { - node._onSort('desc'); - } - } - ] - }); - } - - if (this.parent && this.parent._hasChilds()) { - // create a separator - items.push({ - 'type': 'separator' - }); - - // create append button (for last child node only) - var childs = node.parent.childs; - if (node == childs[childs.length - 1]) { - items.push({ - 'text': 'Append', - 'title': 'Append a new field with type \'auto\' after this field (Ctrl+Shift+Ins)', - 'submenuTitle': 'Select the type of the field to be appended', - 'className': 'append', - 'click': function () { - node._onAppend('', '', 'auto'); - }, - 'submenu': [ - { - 'text': 'Auto', - 'className': 'type-auto', - 'title': titles.auto, - 'click': function () { - node._onAppend('', '', 'auto'); - } - }, - { - 'text': 'Array', - 'className': 'type-array', - 'title': titles.array, - 'click': function () { - node._onAppend('', []); - } - }, - { - 'text': 'Object', - 'className': 'type-object', - 'title': titles.object, - 'click': function () { - node._onAppend('', {}); - } - }, - { - 'text': 'String', - 'className': 'type-string', - 'title': titles.string, - 'click': function () { - node._onAppend('', '', 'string'); - } - } - ] - }); - } - - // create insert button - items.push({ - 'text': 'Insert', - 'title': 'Insert a new field with type \'auto\' before this field (Ctrl+Ins)', - 'submenuTitle': 'Select the type of the field to be inserted', - 'className': 'insert', - 'click': function () { - node._onInsertBefore('', '', 'auto'); - }, - 'submenu': [ - { - 'text': 'Auto', - 'className': 'type-auto', - 'title': titles.auto, - 'click': function () { - node._onInsertBefore('', '', 'auto'); - } - }, - { - 'text': 'Array', - 'className': 'type-array', - 'title': titles.array, - 'click': function () { - node._onInsertBefore('', []); - } - }, - { - 'text': 'Object', - 'className': 'type-object', - 'title': titles.object, - 'click': function () { - node._onInsertBefore('', {}); - } - }, - { - 'text': 'String', - 'className': 'type-string', - 'title': titles.string, - 'click': function () { - node._onInsertBefore('', '', 'string'); - } - } - ] - }); - - // create duplicate button - items.push({ - 'text': 'Duplicate', - 'title': 'Duplicate this field (Ctrl+D)', - 'className': 'duplicate', - 'click': function () { - node._onDuplicate(); - } - }); - - // create remove button - items.push({ - 'text': 'Remove', - 'title': 'Remove this field (Ctrl+Del)', - 'className': 'remove', - 'click': function () { - node._onRemove(); - } - }); - } - - var menu = new ContextMenu(items, {close: onClose}); - menu.show(anchor); -}; - -/** - * get the type of a value - * @param {*} value - * @return {String} type Can be 'object', 'array', 'string', 'auto' - * @private - */ -Node.prototype._getType = function(value) { - if (value instanceof Array) { - return 'array'; - } - if (value instanceof Object) { - return 'object'; - } - if (typeof(value) == 'string' && typeof(this._stringCast(value)) != 'string') { - return 'string'; - } - - return 'auto'; -}; - -/** - * cast contents of a string to the correct type. This can be a string, - * a number, a boolean, etc - * @param {String} str - * @return {*} castedStr - * @private - */ -Node.prototype._stringCast = function(str) { - var lower = str.toLowerCase(), - num = Number(str), // will nicely fail with '123ab' - numFloat = parseFloat(str); // will nicely fail with ' ' - - if (str == '') { - return ''; - } - else if (lower == 'null') { - return null; - } - else if (lower == 'true') { - return true; - } - else if (lower == 'false') { - return false; - } - else if (!isNaN(num) && !isNaN(numFloat)) { - return num; - } - else { - return str; - } -}; - -/** - * escape a text, such that it can be displayed safely in an HTML element - * @param {String} text - * @return {String} escapedText - * @private - */ -Node.prototype._escapeHTML = function (text) { - var htmlEscaped = String(text) - .replace(//g, '>') - .replace(/ /g, '  ') // replace double space with an nbsp and space - .replace(/^ /, ' ') // space at start - .replace(/ $/, ' '); // space at end - - var json = JSON.stringify(htmlEscaped); - return json.substring(1, json.length - 1); -}; - -/** - * unescape a string. - * @param {String} escapedText - * @return {String} text - * @private - */ -Node.prototype._unescapeHTML = function (escapedText) { - var json = '"' + this._escapeJSON(escapedText) + '"'; - var htmlEscaped = util.parse(json); - return htmlEscaped - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/ |\u00A0/g, ' '); -}; - -/** - * escape a text to make it a valid JSON string. The method will: - * - replace unescaped double quotes with '\"' - * - replace unescaped backslash with '\\' - * - replace returns with '\n' - * @param {String} text - * @return {String} escapedText - * @private - */ -Node.prototype._escapeJSON = function (text) { - // TODO: replace with some smart regex (only when a new solution is faster!) - var escaped = ''; - var i = 0, iMax = text.length; - while (i < iMax) { - var c = text.charAt(i); - if (c == '\n') { - escaped += '\\n'; - } - else if (c == '\\') { - escaped += c; - i++; - - c = text.charAt(i); - if ('"\\/bfnrtu'.indexOf(c) == -1) { - escaped += '\\'; // no valid escape character - } - escaped += c; - } - else if (c == '"') { - escaped += '\\"'; - } - else { - escaped += c; - } - i++; - } - - return escaped; -}; - -/** - * @constructor AppendNode - * @extends Node - * @param {TreeEditor} editor - * Create a new AppendNode. This is a special node which is created at the - * end of the list with childs for an object or array - */ -function AppendNode (editor) { - /** @type {TreeEditor} */ - this.editor = editor; - this.dom = {}; -} - -AppendNode.prototype = new Node(); - -/** - * Return a table row with an append button. - * @return {Element} dom TR element - */ -AppendNode.prototype.getDom = function () { - // TODO: implement a new solution for the append node - var dom = this.dom; - - if (dom.tr) { - return dom.tr; - } - - // a row for the append button - var trAppend = document.createElement('tr'); - trAppend.node = this; - dom.tr = trAppend; - - // TODO: consistent naming - - if (this.editor.mode.edit) { - // a cell for the dragarea column - dom.tdDrag = document.createElement('td'); - - // create context menu - var tdMenu = document.createElement('td'); - dom.tdMenu = tdMenu; - var menu = document.createElement('button'); - menu.className = 'contextmenu'; - menu.title = 'Click to open the actions menu (Ctrl+M)'; - dom.menu = menu; - tdMenu.appendChild(dom.menu); - } - - // a cell for the contents (showing text 'empty') - var tdAppend = document.createElement('td'); - var domText = document.createElement('div'); - domText.innerHTML = '(empty)'; - domText.className = 'readonly'; - tdAppend.appendChild(domText); - dom.td = tdAppend; - dom.text = domText; - - this.updateDom(); - - return trAppend; -}; - -/** - * Update the HTML dom of the Node - */ -AppendNode.prototype.updateDom = function () { - var dom = this.dom; - var tdAppend = dom.td; - if (tdAppend) { - tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px'; - // TODO: not so nice hard coded offset - } - - var domText = dom.text; - if (domText) { - domText.innerHTML = '(empty ' + this.parent.type + ')'; - } - - // attach or detach the contents of the append node: - // hide when the parent has childs, show when the parent has no childs - var trAppend = dom.tr; - if (!this.isVisible()) { - if (dom.tr.firstChild) { - if (dom.tdDrag) { - trAppend.removeChild(dom.tdDrag); - } - if (dom.tdMenu) { - trAppend.removeChild(dom.tdMenu); - } - trAppend.removeChild(tdAppend); - } - } - else { - if (!dom.tr.firstChild) { - if (dom.tdDrag) { - trAppend.appendChild(dom.tdDrag); - } - if (dom.tdMenu) { - trAppend.appendChild(dom.tdMenu); - } - trAppend.appendChild(tdAppend); - } - } -}; - -/** - * Check whether the AppendNode is currently visible. - * the AppendNode is visible when its parent has no childs (i.e. is empty). - * @return {boolean} isVisible - */ -AppendNode.prototype.isVisible = function () { - return (this.parent.childs.length == 0); -}; - -/** - * Show a contextmenu for this node - * @param {HTMLElement} anchor The element to attach the menu to. - * @param {function} [onClose] Callback method called when the context menu - * is being closed. - */ -AppendNode.prototype.showContextMenu = function (anchor, onClose) { - var node = this; - var titles = Node.TYPE_TITLES; - var items = [ - // create append button - { - 'text': 'Append', - 'title': 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)', - 'submenuTitle': 'Select the type of the field to be appended', - 'className': 'insert', - 'click': function () { - node._onAppend('', '', 'auto'); - }, - 'submenu': [ - { - 'text': 'Auto', - 'className': 'type-auto', - 'title': titles.auto, - 'click': function () { - node._onAppend('', '', 'auto'); - } - }, - { - 'text': 'Array', - 'className': 'type-array', - 'title': titles.array, - 'click': function () { - node._onAppend('', []); - } - }, - { - 'text': 'Object', - 'className': 'type-object', - 'title': titles.object, - 'click': function () { - node._onAppend('', {}); - } - }, - { - 'text': 'String', - 'className': 'type-string', - 'title': titles.string, - 'click': function () { - node._onAppend('', '', 'string'); - } - } - ] - } - ]; - - var menu = new ContextMenu(items, {close: onClose}); - menu.show(anchor); -}; - -/** - * Handle an event. The event is catched centrally by the editor - * @param {Event} event - */ -AppendNode.prototype.onEvent = function (event) { - var type = event.type; - var target = event.target || event.srcElement; - var dom = this.dom; - - // highlight the append nodes parent - var menu = dom.menu; - if (target == menu) { - if (type == 'mouseover') { - this.editor.highlighter.highlight(this.parent); - } - else if (type == 'mouseout') { - this.editor.highlighter.unhighlight(); - } - } - - // context menu events - if (type == 'click' && target == dom.menu) { - var highlighter = this.editor.highlighter; - highlighter.highlight(this.parent); - highlighter.lock(); - util.addClassName(dom.menu, 'selected'); - this.showContextMenu(dom.menu, function () { - util.removeClassName(dom.menu, 'selected'); - highlighter.unlock(); - highlighter.unhighlight(); - }); - } - - if (type == 'keydown') { - this.onKeyDown(event); - } -}; - -/** - * A context menu - * @param {Object[]} items Array containing the menu structure - * TODO: describe structure - * @param {Object} [options] Object with options. Available options: - * {function} close Callback called when the - * context menu is being closed. - * @constructor - */ -function ContextMenu (items, options) { - this.dom = {}; - - var me = this; - var dom = this.dom; - this.anchor = undefined; - this.items = items; - this.eventListeners = {}; - this.selection = undefined; // holds the selection before the menu was opened - this.visibleSubmenu = undefined; - this.onClose = options ? options.close : undefined; - - // create a container element - var menu = document.createElement('div'); - menu.className = 'jsoneditor-contextmenu'; - dom.menu = menu; - - // create a list to hold the menu items - var list = document.createElement('ul'); - list.className = 'menu'; - menu.appendChild(list); - dom.list = list; - dom.items = []; // list with all buttons - - // create a (non-visible) button to set the focus to the menu - var focusButton = document.createElement('button'); - dom.focusButton = focusButton; - var li = document.createElement('li'); - li.style.overflow = 'hidden'; - li.style.height = '0'; - li.appendChild(focusButton); - list.appendChild(li); - - function createMenuItems (list, domItems, items) { - items.forEach(function (item) { - if (item.type == 'separator') { - // create a separator - var separator = document.createElement('div'); - separator.className = 'separator'; - li = document.createElement('li'); - li.appendChild(separator); - list.appendChild(li); - } - else { - var domItem = {}; - - // create a menu item - var li = document.createElement('li'); - list.appendChild(li); - - // create a button in the menu item - var button = document.createElement('button'); - button.className = item.className; - domItem.button = button; - if (item.title) { - button.title = item.title; - } - if (item.click) { - button.onclick = function () { - me.hide(); - item.click(); - }; - } - li.appendChild(button); - - // create the contents of the button - if (item.submenu) { - // add the icon to the button - var divIcon = document.createElement('div'); - divIcon.className = 'icon'; - button.appendChild(divIcon); - button.appendChild(document.createTextNode(item.text)); - - var buttonSubmenu; - if (item.click) { - // submenu and a button with a click handler - button.className += ' default'; - - var buttonExpand = document.createElement('button'); - domItem.buttonExpand = buttonExpand; - buttonExpand.className = 'expand'; - buttonExpand.innerHTML = '
'; - li.appendChild(buttonExpand); - if (item.submenuTitle) { - buttonExpand.title = item.submenuTitle; - } - - buttonSubmenu = buttonExpand; - } - else { - // submenu and a button without a click handler - var divExpand = document.createElement('div'); - divExpand.className = 'expand'; - button.appendChild(divExpand); - - buttonSubmenu = button; - } - - // attach a handler to expand/collapse the submenu - buttonSubmenu.onclick = function () { - me._onExpandItem(domItem); - buttonSubmenu.focus(); - }; - - // create the submenu - var domSubItems = []; - domItem.subItems = domSubItems; - var ul = document.createElement('ul'); - domItem.ul = ul; - ul.className = 'menu'; - ul.style.height = '0'; - li.appendChild(ul); - createMenuItems(ul, domSubItems, item.submenu); - } - else { - // no submenu, just a button with clickhandler - button.innerHTML = '
' + item.text; - } - - domItems.push(domItem); - } - }); - } - createMenuItems(list, this.dom.items, items); - - // TODO: when the editor is small, show the submenu on the right instead of inline? - - // calculate the max height of the menu with one submenu expanded - this.maxHeight = 0; // height in pixels - items.forEach(function (item) { - var height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24; - me.maxHeight = Math.max(me.maxHeight, height); - }); -} - -/** - * Get the currently visible buttons - * @return {Array.} buttons - * @private - */ -ContextMenu.prototype._getVisibleButtons = function () { - var buttons = []; - var me = this; - this.dom.items.forEach(function (item) { - buttons.push(item.button); - if (item.buttonExpand) { - buttons.push(item.buttonExpand); - } - if (item.subItems && item == me.expandedItem) { - item.subItems.forEach(function (subItem) { - buttons.push(subItem.button); - if (subItem.buttonExpand) { - buttons.push(subItem.buttonExpand); - } - // TODO: change to fully recursive method - }); - } - }); - - return buttons; -}; - -// currently displayed context menu, a singleton. We may only have one visible context menu -ContextMenu.visibleMenu = undefined; - -/** - * Attach the menu to an anchor - * @param {HTMLElement} anchor - */ -ContextMenu.prototype.show = function (anchor) { - this.hide(); - - // calculate whether the menu fits below the anchor - var windowHeight = window.innerHeight, - windowScroll = (window.pageYOffset || document.scrollTop), - windowBottom = windowHeight + windowScroll, - anchorHeight = anchor.offsetHeight, - menuHeight = this.maxHeight; - - // position the menu - var left = util.getAbsoluteLeft(anchor); - var top = util.getAbsoluteTop(anchor); - if (top + anchorHeight + menuHeight < windowBottom) { - // display the menu below the anchor - this.dom.menu.style.left = left + 'px'; - this.dom.menu.style.top = (top + anchorHeight) + 'px'; - this.dom.menu.style.bottom = ''; - } - else { - // display the menu above the anchor - this.dom.menu.style.left = left + 'px'; - this.dom.menu.style.top = ''; - this.dom.menu.style.bottom = (windowHeight - top) + 'px'; - } - - // attach the menu to the document - document.body.appendChild(this.dom.menu); - - // create and attach event listeners - var me = this; - var list = this.dom.list; - this.eventListeners.mousedown = util.addEventListener( - document, 'mousedown', function (event) { - // hide menu on click outside of the menu - var target = event.target; - if ((target != list) && !me._isChildOf(target, list)) { - me.hide(); - event.stopPropagation(); - event.preventDefault(); - } - }); - this.eventListeners.mousewheel = util.addEventListener( - document, 'mousewheel', function (event) { - // block scrolling when context menu is visible - event.stopPropagation(); - event.preventDefault(); - }); - this.eventListeners.keydown = util.addEventListener( - document, 'keydown', function (event) { - me._onKeyDown(event); - }); - - // move focus to the first button in the context menu - this.selection = util.getSelection(); - this.anchor = anchor; - setTimeout(function () { - me.dom.focusButton.focus(); - }, 0); - - if (ContextMenu.visibleMenu) { - ContextMenu.visibleMenu.hide(); - } - ContextMenu.visibleMenu = this; -}; - -/** - * Hide the context menu if visible - */ -ContextMenu.prototype.hide = function () { - // remove the menu from the DOM - if (this.dom.menu.parentNode) { - this.dom.menu.parentNode.removeChild(this.dom.menu); - if (this.onClose) { - this.onClose(); - } - } - - // remove all event listeners - // all event listeners are supposed to be attached to document. - for (var name in this.eventListeners) { - if (this.eventListeners.hasOwnProperty(name)) { - var fn = this.eventListeners[name]; - if (fn) { - util.removeEventListener(document, name, fn); - } - delete this.eventListeners[name]; - } - } - - if (ContextMenu.visibleMenu == this) { - ContextMenu.visibleMenu = undefined; - } -}; - -/** - * Expand a submenu - * Any currently expanded submenu will be hided. - * @param {Object} domItem - * @private - */ -ContextMenu.prototype._onExpandItem = function (domItem) { - var me = this; - var alreadyVisible = (domItem == this.expandedItem); - - // hide the currently visible submenu - var expandedItem = this.expandedItem; - if (expandedItem) { - //var ul = expandedItem.ul; - expandedItem.ul.style.height = '0'; - expandedItem.ul.style.padding = ''; - setTimeout(function () { - if (me.expandedItem != expandedItem) { - expandedItem.ul.style.display = ''; - util.removeClassName(expandedItem.ul.parentNode, 'selected'); - } - }, 300); // timeout duration must match the css transition duration - this.expandedItem = undefined; - } - - if (!alreadyVisible) { - var ul = domItem.ul; - ul.style.display = 'block'; - var height = ul.clientHeight; // force a reflow in Firefox - setTimeout(function () { - if (me.expandedItem == domItem) { - ul.style.height = (ul.childNodes.length * 24) + 'px'; - ul.style.padding = '5px 10px'; - } - }, 0); - util.addClassName(ul.parentNode, 'selected'); - this.expandedItem = domItem; - } -}; - -/** - * Handle onkeydown event - * @param {Event} event - * @private - */ -ContextMenu.prototype._onKeyDown = function (event) { - var target = event.target; - var keynum = event.which; - var handled = false; - var buttons, targetIndex, prevButton, nextButton; - - if (keynum == 27) { // ESC - // hide the menu on ESC key - - // restore previous selection and focus - if (this.selection) { - util.setSelection(this.selection); - } - if (this.anchor) { - this.anchor.focus(); - } - - this.hide(); - - handled = true; - } - else if (keynum == 9) { // Tab - if (!event.shiftKey) { // Tab - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - if (targetIndex == buttons.length - 1) { - // move to first button - buttons[0].focus(); - handled = true; - } - } - else { // Shift+Tab - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - if (targetIndex == 0) { - // move to last button - buttons[buttons.length - 1].focus(); - handled = true; - } - } - } - else if (keynum == 37) { // Arrow Left - if (target.className == 'expand') { - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - prevButton = buttons[targetIndex - 1]; - if (prevButton) { - prevButton.focus(); - } - } - handled = true; - } - else if (keynum == 38) { // Arrow Up - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - prevButton = buttons[targetIndex - 1]; - if (prevButton && prevButton.className == 'expand') { - // skip expand button - prevButton = buttons[targetIndex - 2]; - } - if (!prevButton) { - // move to last button - prevButton = buttons[buttons.length - 1]; - } - if (prevButton) { - prevButton.focus(); - } - handled = true; - } - else if (keynum == 39) { // Arrow Right - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - nextButton = buttons[targetIndex + 1]; - if (nextButton && nextButton.className == 'expand') { - nextButton.focus(); - } - handled = true; - } - else if (keynum == 40) { // Arrow Down - buttons = this._getVisibleButtons(); - targetIndex = buttons.indexOf(target); - nextButton = buttons[targetIndex + 1]; - if (nextButton && nextButton.className == 'expand') { - // skip expand button - nextButton = buttons[targetIndex + 2]; - } - if (!nextButton) { - // move to first button - nextButton = buttons[0]; - } - if (nextButton) { - nextButton.focus(); - handled = true; - } - handled = true; - } - // TODO: arrow left and right - - if (handled) { - event.stopPropagation(); - event.preventDefault(); - } -}; - -/** - * Test if an element is a child of a parent element. - * @param {Element} child - * @param {Element} parent - * @return {boolean} isChild - */ -ContextMenu.prototype._isChildOf = function (child, parent) { - var e = child.parentNode; - while (e) { - if (e == parent) { - return true; - } - e = e.parentNode; - } - - return false; -}; - - -/** - * @constructor History - * Store action history, enables undo and redo - * @param {JSONEditor} editor - */ -function History (editor) { - this.editor = editor; - this.clear(); - - // map with all supported actions - this.actions = { - 'editField': { - 'undo': function (params) { - params.node.updateField(params.oldValue); - }, - 'redo': function (params) { - params.node.updateField(params.newValue); - } - }, - 'editValue': { - 'undo': function (params) { - params.node.updateValue(params.oldValue); - }, - 'redo': function (params) { - params.node.updateValue(params.newValue); - } - }, - 'appendNode': { - 'undo': function (params) { - params.parent.removeChild(params.node); - }, - 'redo': function (params) { - params.parent.appendChild(params.node); - } - }, - 'insertBeforeNode': { - 'undo': function (params) { - params.parent.removeChild(params.node); - }, - 'redo': function (params) { - params.parent.insertBefore(params.node, params.beforeNode); - } - }, - 'insertAfterNode': { - 'undo': function (params) { - params.parent.removeChild(params.node); - }, - 'redo': function (params) { - params.parent.insertAfter(params.node, params.afterNode); - } - }, - 'removeNode': { - 'undo': function (params) { - var parent = params.parent; - var beforeNode = parent.childs[params.index] || parent.append; - parent.insertBefore(params.node, beforeNode); - }, - 'redo': function (params) { - params.parent.removeChild(params.node); - } - }, - 'duplicateNode': { - 'undo': function (params) { - params.parent.removeChild(params.clone); - }, - 'redo': function (params) { - params.parent.insertAfter(params.clone, params.node); - } - }, - 'changeType': { - 'undo': function (params) { - params.node.changeType(params.oldType); - }, - 'redo': function (params) { - params.node.changeType(params.newType); - } - }, - 'moveNode': { - 'undo': function (params) { - params.startParent.moveTo(params.node, params.startIndex); - }, - 'redo': function (params) { - params.endParent.moveTo(params.node, params.endIndex); - } - }, - 'sort': { - 'undo': function (params) { - var node = params.node; - node.hideChilds(); - node.sort = params.oldSort; - node.childs = params.oldChilds; - node.showChilds(); - }, - 'redo': function (params) { - var node = params.node; - node.hideChilds(); - node.sort = params.newSort; - node.childs = params.newChilds; - node.showChilds(); - } - } - - // TODO: restore the original caret position and selection with each undo - // TODO: implement history for actions "expand", "collapse", "scroll", "setDocument" - }; -} - -/** - * The method onChange is executed when the History is changed, and can - * be overloaded. - */ -History.prototype.onChange = function () {}; - -/** - * Add a new action to the history - * @param {String} action The executed action. Available actions: "editField", - * "editValue", "changeType", "appendNode", - * "removeNode", "duplicateNode", "moveNode" - * @param {Object} params Object containing parameters describing the change. - * The parameters in params depend on the action (for - * example for "editValue" the Node, old value, and new - * value are provided). params contains all information - * needed to undo or redo the action. - */ -History.prototype.add = function (action, params) { - this.index++; - this.history[this.index] = { - 'action': action, - 'params': params, - 'timestamp': new Date() - }; - - // remove redo actions which are invalid now - if (this.index < this.history.length - 1) { - this.history.splice(this.index + 1, this.history.length - this.index - 1); - } - - // fire onchange event - this.onChange(); -}; - -/** - * Clear history - */ -History.prototype.clear = function () { - this.history = []; - this.index = -1; - - // fire onchange event - this.onChange(); -}; - -/** - * Check if there is an action available for undo - * @return {Boolean} canUndo - */ -History.prototype.canUndo = function () { - return (this.index >= 0); -}; - -/** - * Check if there is an action available for redo - * @return {Boolean} canRedo - */ -History.prototype.canRedo = function () { - return (this.index < this.history.length - 1); -}; - -/** - * Undo the last action - */ -History.prototype.undo = function () { - if (this.canUndo()) { - var obj = this.history[this.index]; - if (obj) { - var action = this.actions[obj.action]; - if (action && action.undo) { - action.undo(obj.params); - if (obj.params.oldSelection) { - this.editor.setSelection(obj.params.oldSelection); - } - } - else { - util.log('Error: unknown action "' + obj.action + '"'); - } - } - this.index--; - - // fire onchange event - this.onChange(); - } -}; - -/** - * Redo the last action - */ -History.prototype.redo = function () { - if (this.canRedo()) { - this.index++; - - var obj = this.history[this.index]; - if (obj) { - var action = this.actions[obj.action]; - if (action && action.redo) { - action.redo(obj.params); - if (obj.params.newSelection) { - this.editor.setSelection(obj.params.newSelection); - } - } - else { - util.log('Error: unknown action "' + obj.action + '"'); - } - } - - // fire onchange event - this.onChange(); - } -}; - -/** - * create a mode box to be used in the editor menu's - * @param {JSONEditor} editor - * @param {String[]} modes Available modes: 'code', 'form', 'text', 'tree', 'view' - * @param {String} current Available modes: 'code', 'form', 'text', 'tree', 'view' - * @returns {HTMLElement} box - */ -function createModeBox(editor, modes, current) { - /** - * Switch the mode of the editor - * @param {String} mode - */ - function switchMode(mode) { - // switch mode - editor.setMode(mode); - - // restore focus on mode box - var modeBox = editor.dom && editor.dom.modeBox; - if (modeBox) { - modeBox.focus(); - } - } - - // available modes - var availableModes = { - code: { - 'text': 'Code', - 'title': 'Switch to code highlighter', - 'click': function () { - switchMode('code') - } - }, - form: { - 'text': 'Form', - 'title': 'Switch to form editor', - 'click': function () { - switchMode('form'); - } - }, - text: { - 'text': 'Text', - 'title': 'Switch to plain text editor', - 'click': function () { - switchMode('text'); - } - }, - tree: { - 'text': 'Tree', - 'title': 'Switch to tree editor', - 'click': function () { - switchMode('tree'); - } - }, - view: { - 'text': 'View', - 'title': 'Switch to tree view', - 'click': function () { - switchMode('view'); - } - } - }; - - // list the selected modes - var items = []; - for (var i = 0; i < modes.length; i++) { - var mode = modes[i]; - var item = availableModes[mode]; - if (!item) { - throw new Error('Unknown mode "' + mode + '"'); - } - - item.className = 'type-modes' + ((current == mode) ? ' selected' : ''); - items.push(item); - } - - // retrieve the title of current mode - var currentMode = availableModes[current]; - if (!currentMode) { - throw new Error('Unknown mode "' + current + '"'); - } - var currentTitle = currentMode.text; - - // create the html element - var box = document.createElement('button'); - box.className = 'modes separator'; - box.innerHTML = currentTitle + ' ▾'; - box.title = 'Switch editor mode'; - box.onclick = function () { - var menu = new ContextMenu(items); - menu.show(box); - }; - - return box; -} - -/** - * @constructor SearchBox - * Create a search box in given HTML container - * @param {JSONEditor} editor The JSON Editor to attach to - * @param {Element} container HTML container element of where to - * create the search box - */ -function SearchBox (editor, container) { - var searchBox = this; - - this.editor = editor; - this.timeout = undefined; - this.delay = 200; // ms - this.lastText = undefined; - - this.dom = {}; - this.dom.container = container; - - var table = document.createElement('table'); - this.dom.table = table; - table.className = 'search'; - container.appendChild(table); - var tbody = document.createElement('tbody'); - this.dom.tbody = tbody; - table.appendChild(tbody); - var tr = document.createElement('tr'); - tbody.appendChild(tr); - - var td = document.createElement('td'); - tr.appendChild(td); - var results = document.createElement('div'); - this.dom.results = results; - results.className = 'results'; - td.appendChild(results); - - td = document.createElement('td'); - tr.appendChild(td); - var divInput = document.createElement('div'); - this.dom.input = divInput; - divInput.className = 'frame'; - divInput.title = 'Search fields and values'; - td.appendChild(divInput); - - // table to contain the text input and search button - var tableInput = document.createElement('table'); - divInput.appendChild(tableInput); - var tbodySearch = document.createElement('tbody'); - tableInput.appendChild(tbodySearch); - tr = document.createElement('tr'); - tbodySearch.appendChild(tr); - - var refreshSearch = document.createElement('button'); - refreshSearch.className = 'refresh'; - td = document.createElement('td'); - td.appendChild(refreshSearch); - tr.appendChild(td); - - var search = document.createElement('input'); - this.dom.search = search; - search.oninput = function (event) { - searchBox._onDelayedSearch(event); - }; - search.onchange = function (event) { // For IE 9 - searchBox._onSearch(event); - }; - search.onkeydown = function (event) { - searchBox._onKeyDown(event); - }; - search.onkeyup = function (event) { - searchBox._onKeyUp(event); - }; - refreshSearch.onclick = function (event) { - search.select(); - }; - - // TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819 - td = document.createElement('td'); - td.appendChild(search); - tr.appendChild(td); - - var searchNext = document.createElement('button'); - searchNext.title = 'Next result (Enter)'; - searchNext.className = 'next'; - searchNext.onclick = function () { - searchBox.next(); - }; - td = document.createElement('td'); - td.appendChild(searchNext); - tr.appendChild(td); - - var searchPrevious = document.createElement('button'); - searchPrevious.title = 'Previous result (Shift+Enter)'; - searchPrevious.className = 'previous'; - searchPrevious.onclick = function () { - searchBox.previous(); - }; - td = document.createElement('td'); - td.appendChild(searchPrevious); - tr.appendChild(td); -} - -/** - * Go to the next search result - * @param {boolean} [focus] If true, focus will be set to the next result - * focus is false by default. - */ -SearchBox.prototype.next = function(focus) { - if (this.results != undefined) { - var index = (this.resultIndex != undefined) ? this.resultIndex + 1 : 0; - if (index > this.results.length - 1) { - index = 0; - } - this._setActiveResult(index, focus); - } -}; - -/** - * Go to the prevous search result - * @param {boolean} [focus] If true, focus will be set to the next result - * focus is false by default. - */ -SearchBox.prototype.previous = function(focus) { - if (this.results != undefined) { - var max = this.results.length - 1; - var index = (this.resultIndex != undefined) ? this.resultIndex - 1 : max; - if (index < 0) { - index = max; - } - this._setActiveResult(index, focus); - } -}; - -/** - * Set new value for the current active result - * @param {Number} index - * @param {boolean} [focus] If true, focus will be set to the next result. - * focus is false by default. - * @private - */ -SearchBox.prototype._setActiveResult = function(index, focus) { - // de-activate current active result - if (this.activeResult) { - var prevNode = this.activeResult.node; - var prevElem = this.activeResult.elem; - if (prevElem == 'field') { - delete prevNode.searchFieldActive; - } - else { - delete prevNode.searchValueActive; - } - prevNode.updateDom(); - } - - if (!this.results || !this.results[index]) { - // out of range, set to undefined - this.resultIndex = undefined; - this.activeResult = undefined; - return; - } - - this.resultIndex = index; - - // set new node active - var node = this.results[this.resultIndex].node; - var elem = this.results[this.resultIndex].elem; - if (elem == 'field') { - node.searchFieldActive = true; - } - else { - node.searchValueActive = true; - } - this.activeResult = this.results[this.resultIndex]; - node.updateDom(); - - // TODO: not so nice that the focus is only set after the animation is finished - node.scrollTo(function () { - if (focus) { - node.focus(elem); - } - }); -}; - -/** - * Cancel any running onDelayedSearch. - * @private - */ -SearchBox.prototype._clearDelay = function() { - if (this.timeout != undefined) { - clearTimeout(this.timeout); - delete this.timeout; - } -}; - -/** - * Start a timer to execute a search after a short delay. - * Used for reducing the number of searches while typing. - * @param {Event} event - * @private - */ -SearchBox.prototype._onDelayedSearch = function (event) { - // execute the search after a short delay (reduces the number of - // search actions while typing in the search text box) - this._clearDelay(); - var searchBox = this; - this.timeout = setTimeout(function (event) { - searchBox._onSearch(event); - }, - this.delay); -}; - -/** - * Handle onSearch event - * @param {Event} event - * @param {boolean} [forceSearch] If true, search will be executed again even - * when the search text is not changed. - * Default is false. - * @private - */ -SearchBox.prototype._onSearch = function (event, forceSearch) { - this._clearDelay(); - - var value = this.dom.search.value; - var text = (value.length > 0) ? value : undefined; - if (text != this.lastText || forceSearch) { - // only search again when changed - this.lastText = text; - this.results = this.editor.search(text); - this._setActiveResult(undefined); - - // display search results - if (text != undefined) { - var resultCount = this.results.length; - switch (resultCount) { - case 0: this.dom.results.innerHTML = 'no results'; break; - case 1: this.dom.results.innerHTML = '1 result'; break; - default: this.dom.results.innerHTML = resultCount + ' results'; break; - } - } - else { - this.dom.results.innerHTML = ''; - } - } -}; - -/** - * Handle onKeyDown event in the input box - * @param {Event} event - * @private - */ -SearchBox.prototype._onKeyDown = function (event) { - var keynum = event.which; - if (keynum == 27) { // ESC - this.dom.search.value = ''; // clear search - this._onSearch(event); - event.preventDefault(); - event.stopPropagation(); - } - else if (keynum == 13) { // Enter - if (event.ctrlKey) { - // force to search again - this._onSearch(event, true); - } - else if (event.shiftKey) { - // move to the previous search result - this.previous(); - } - else { - // move to the next search result - this.next(); - } - event.preventDefault(); - event.stopPropagation(); - } -}; - -/** - * Handle onKeyUp event in the input box - * @param {Event} event - * @private - */ -SearchBox.prototype._onKeyUp = function (event) { - var keynum = event.keyCode; - if (keynum != 27 && keynum != 13) { // !show and !Enter - this._onDelayedSearch(event); // For IE 9 - } -}; - -/** - * The highlighter can highlight/unhighlight a node, and - * animate the visibility of a context menu. - * @constructor Highlighter - */ -function Highlighter () { - this.locked = false; -} - -/** - * Hightlight given node and its childs - * @param {Node} node - */ -Highlighter.prototype.highlight = function (node) { - if (this.locked) { - return; - } - - if (this.node != node) { - // unhighlight current node - if (this.node) { - this.node.setHighlight(false); - } - - // highlight new node - this.node = node; - this.node.setHighlight(true); - } - - // cancel any current timeout - this._cancelUnhighlight(); -}; - -/** - * Unhighlight currently highlighted node. - * Will be done after a delay - */ -Highlighter.prototype.unhighlight = function () { - if (this.locked) { - return; - } - - var me = this; - if (this.node) { - this._cancelUnhighlight(); - - // do the unhighlighting after a small delay, to prevent re-highlighting - // the same node when moving from the drag-icon to the contextmenu-icon - // or vice versa. - this.unhighlightTimer = setTimeout(function () { - me.node.setHighlight(false); - me.node = undefined; - me.unhighlightTimer = undefined; - }, 0); - } -}; - -/** - * Cancel an unhighlight action (if before the timeout of the unhighlight action) - * @private - */ -Highlighter.prototype._cancelUnhighlight = function () { - if (this.unhighlightTimer) { - clearTimeout(this.unhighlightTimer); - this.unhighlightTimer = undefined; - } -}; - -/** - * Lock highlighting or unhighlighting nodes. - * methods highlight and unhighlight do not work while locked. - */ -Highlighter.prototype.lock = function () { - this.locked = true; -}; - -/** - * Unlock highlighting or unhighlighting nodes - */ -Highlighter.prototype.unlock = function () { - this.locked = false; -}; - -// create namespace -util = {}; - -/** - * Parse JSON using the parser built-in in the browser. - * On exception, the jsonString is validated and a detailed error is thrown. - * @param {String} jsonString - */ -util.parse = function parse(jsonString) { - try { - return JSON.parse(jsonString); - } - catch (err) { - // try to throw a more detailed error message using validate - util.validate(jsonString); - throw err; - } -}; - -/** - * Validate a string containing a JSON object - * This method uses JSONLint to validate the String. If JSONLint is not - * available, the built-in JSON parser of the browser is used. - * @param {String} jsonString String with an (invalid) JSON object - * @throws Error - */ -util.validate = function validate(jsonString) { - if (typeof(jsonlint) != 'undefined') { - jsonlint.parse(jsonString); - } - else { - JSON.parse(jsonString); - } -}; - -/** - * Extend object a with the properties of object b - * @param {Object} a - * @param {Object} b - * @return {Object} a - */ -util.extend = function extend(a, b) { - for (var prop in b) { - if (b.hasOwnProperty(prop)) { - a[prop] = b[prop]; - } - } - return a; -}; - -/** - * Remove all properties from object a - * @param {Object} a - * @return {Object} a - */ -util.clear = function clear (a) { - for (var prop in a) { - if (a.hasOwnProperty(prop)) { - delete a[prop]; - } - } - return a; -}; - -/** - * Output text to the console, if console is available - * @param {...*} args - */ -util.log = function log (args) { - if (typeof console !== 'undefined' && typeof console.log === 'function') { - console.log.apply(console, arguments); - } -}; - -/** - * Get the type of an object - * @param {*} object - * @return {String} type - */ -util.type = function type (object) { - if (object === null) { - return 'null'; - } - if (object === undefined) { - return 'undefined'; - } - if ((object instanceof Number) || (typeof object === 'number')) { - return 'number'; - } - if ((object instanceof String) || (typeof object === 'string')) { - return 'string'; - } - if ((object instanceof Boolean) || (typeof object === 'boolean')) { - return 'boolean'; - } - if ((object instanceof RegExp) || (typeof object === 'regexp')) { - return 'regexp'; - } - if (Array.isArray(object)) { - return 'array'; - } - - return 'object'; -}; - -/** - * Test whether a text contains a url (matches when a string starts - * with 'http://*' or 'https://*' and has no whitespace characters) - * @param {String} text - */ -var isUrlRegex = /^https?:\/\/\S+$/; -util.isUrl = function isUrl (text) { - return (typeof text == 'string' || text instanceof String) && - isUrlRegex.test(text); -}; - -/** - * Retrieve the absolute left value of a DOM element - * @param {Element} elem A dom element, for example a div - * @return {Number} left The absolute left position of this element - * in the browser page. - */ -util.getAbsoluteLeft = function getAbsoluteLeft(elem) { - var rect = elem.getBoundingClientRect(); - return rect.left + window.pageXOffset || document.scrollLeft || 0; -}; - -/** - * Retrieve the absolute top value of a DOM element - * @param {Element} elem A dom element, for example a div - * @return {Number} top The absolute top position of this element - * in the browser page. - */ -util.getAbsoluteTop = function getAbsoluteTop(elem) { - var rect = elem.getBoundingClientRect(); - return rect.top + window.pageYOffset || document.scrollTop || 0; -}; - -/** - * add a className to the given elements style - * @param {Element} elem - * @param {String} className - */ -util.addClassName = function addClassName(elem, className) { - var classes = elem.className.split(' '); - if (classes.indexOf(className) == -1) { - classes.push(className); // add the class to the array - elem.className = classes.join(' '); - } -}; - -/** - * add a className to the given elements style - * @param {Element} elem - * @param {String} className - */ -util.removeClassName = function removeClassName(elem, className) { - var classes = elem.className.split(' '); - var index = classes.indexOf(className); - if (index != -1) { - classes.splice(index, 1); // remove the class from the array - elem.className = classes.join(' '); - } -}; - -/** - * Strip the formatting from the contents of a div - * the formatting from the div itself is not stripped, only from its childs. - * @param {Element} divElement - */ -util.stripFormatting = function stripFormatting(divElement) { - var childs = divElement.childNodes; - for (var i = 0, iMax = childs.length; i < iMax; i++) { - var child = childs[i]; - - // remove the style - if (child.style) { - // TODO: test if child.attributes does contain style - child.removeAttribute('style'); - } - - // remove all attributes - var attributes = child.attributes; - if (attributes) { - for (var j = attributes.length - 1; j >= 0; j--) { - var attribute = attributes[j]; - if (attribute.specified == true) { - child.removeAttribute(attribute.name); - } - } - } - - // recursively strip childs - util.stripFormatting(child); - } -}; - -/** - * Set focus to the end of an editable div - * code from Nico Burns - * http://stackoverflow.com/users/140293/nico-burns - * http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity - * @param {Element} contentEditableElement A content editable div - */ -util.setEndOfContentEditable = function setEndOfContentEditable(contentEditableElement) { - var range, selection; - if(document.createRange) { - range = document.createRange();//Create a range (a range is a like the selection but invisible) - range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range - range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start - selection = window.getSelection();//get the selection object (allows you to change selection) - selection.removeAllRanges();//remove any selections already made - selection.addRange(range);//make the range you have just created the visible selection - } -}; - -/** - * Select all text of a content editable div. - * http://stackoverflow.com/a/3806004/1262753 - * @param {Element} contentEditableElement A content editable div - */ -util.selectContentEditable = function selectContentEditable(contentEditableElement) { - if (!contentEditableElement || contentEditableElement.nodeName != 'DIV') { - return; - } - - var sel, range; - if (window.getSelection && document.createRange) { - range = document.createRange(); - range.selectNodeContents(contentEditableElement); - sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - } -}; - -/** - * Get text selection - * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore - * @return {Range | TextRange | null} range - */ -util.getSelection = function getSelection() { - if (window.getSelection) { - var sel = window.getSelection(); - if (sel.getRangeAt && sel.rangeCount) { - return sel.getRangeAt(0); - } - } - return null; -}; - -/** - * Set text selection - * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore - * @param {Range | TextRange | null} range - */ -util.setSelection = function setSelection(range) { - if (range) { - if (window.getSelection) { - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - } - } -}; - -/** - * Get selected text range - * @return {Object} params object containing parameters: - * {Number} startOffset - * {Number} endOffset - * {Element} container HTML element holding the - * selected text element - * Returns null if no text selection is found - */ -util.getSelectionOffset = function getSelectionOffset() { - var range = util.getSelection(); - - if (range && 'startOffset' in range && 'endOffset' in range && - range.startContainer && (range.startContainer == range.endContainer)) { - return { - startOffset: range.startOffset, - endOffset: range.endOffset, - container: range.startContainer.parentNode - }; - } - - return null; -}; - -/** - * Set selected text range in given element - * @param {Object} params An object containing: - * {Element} container - * {Number} startOffset - * {Number} endOffset - */ -util.setSelectionOffset = function setSelectionOffset(params) { - if (document.createRange && window.getSelection) { - var selection = window.getSelection(); - if(selection) { - var range = document.createRange(); - // TODO: do not suppose that the first child of the container is a textnode, - // but recursively find the textnodes - range.setStart(params.container.firstChild, params.startOffset); - range.setEnd(params.container.firstChild, params.endOffset); - - util.setSelection(range); - } - } -}; - -/** - * Get the inner text of an HTML element (for example a div element) - * @param {Element} element - * @param {Object} [buffer] - * @return {String} innerText - */ -util.getInnerText = function getInnerText(element, buffer) { - var first = (buffer == undefined); - if (first) { - buffer = { - 'text': '', - 'flush': function () { - var text = this.text; - this.text = ''; - return text; - }, - 'set': function (text) { - this.text = text; - } - }; - } - - // text node - if (element.nodeValue) { - return buffer.flush() + element.nodeValue; - } - - // divs or other HTML elements - if (element.hasChildNodes()) { - var childNodes = element.childNodes; - var innerText = ''; - - for (var i = 0, iMax = childNodes.length; i < iMax; i++) { - var child = childNodes[i]; - - if (child.nodeName == 'DIV' || child.nodeName == 'P') { - var prevChild = childNodes[i - 1]; - var prevName = prevChild ? prevChild.nodeName : undefined; - if (prevName && prevName != 'DIV' && prevName != 'P' && prevName != 'BR') { - innerText += '\n'; - buffer.flush(); - } - innerText += util.getInnerText(child, buffer); - buffer.set('\n'); - } - else if (child.nodeName == 'BR') { - innerText += buffer.flush(); - buffer.set('\n'); - } - else { - innerText += util.getInnerText(child, buffer); - } - } - - return innerText; - } - else { - if (element.nodeName == 'P' && util.getInternetExplorerVersion() != -1) { - // On Internet Explorer, a

with hasChildNodes()==false is - // rendered with a new line. Note that a

with - // hasChildNodes()==true is rendered without a new line - // Other browsers always ensure there is a
inside the

, - // and if not, the

does not render a new line - return buffer.flush(); - } - } - - // br or unknown - return ''; -}; - -/** - * Returns the version of Internet Explorer or a -1 - * (indicating the use of another browser). - * Source: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx - * @return {Number} Internet Explorer version, or -1 in case of an other browser - */ -util.getInternetExplorerVersion = function getInternetExplorerVersion() { - if (_ieVersion == -1) { - var rv = -1; // Return value assumes failure. - if (navigator.appName == 'Microsoft Internet Explorer') - { - var ua = navigator.userAgent; - var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); - if (re.exec(ua) != null) { - rv = parseFloat( RegExp.$1 ); - } - } - - _ieVersion = rv; - } - - return _ieVersion; -}; - -/** - * Test whether the current browser is Firefox - * @returns {boolean} isFirefox - */ -util.isFirefox = function isFirefox () { - return (navigator.userAgent.indexOf("Firefox") != -1); -}; - -/** - * cached internet explorer version - * @type {Number} - * @private - */ -var _ieVersion = -1; - -/** - * Add and event listener. Works for all browsers - * @param {Element} element An html element - * @param {string} action The action, for example "click", - * without the prefix "on" - * @param {function} listener The callback function to be executed - * @param {boolean} [useCapture] false by default - * @return {function} the created event listener - */ -util.addEventListener = function addEventListener(element, action, listener, useCapture) { - if (element.addEventListener) { - if (useCapture === undefined) - useCapture = false; - - if (action === "mousewheel" && util.isFirefox()) { - action = "DOMMouseScroll"; // For Firefox - } - - element.addEventListener(action, listener, useCapture); - return listener; - } else if (element.attachEvent) { - // Old IE browsers - var f = function () { - return listener.call(element, window.event); - }; - element.attachEvent("on" + action, f); - return f; - } -}; - -/** - * Remove an event listener from an element - * @param {Element} element An html dom element - * @param {string} action The name of the event, for example "mousedown" - * @param {function} listener The listener function - * @param {boolean} [useCapture] false by default - */ -util.removeEventListener = function removeEventListener(element, action, listener, useCapture) { - if (element.removeEventListener) { - if (useCapture === undefined) - useCapture = false; - - if (action === "mousewheel" && util.isFirefox()) { - action = "DOMMouseScroll"; // For Firefox - } - - element.removeEventListener(action, listener, useCapture); - } else if (element.detachEvent) { - // Old IE browsers - element.detachEvent("on" + action, listener); - } -}; - - -// module exports -var jsoneditor = { - 'JSONEditor': JSONEditor, - 'JSONFormatter': function () { - throw new Error('JSONFormatter is deprecated. ' + - 'Use JSONEditor with mode "text" or "code" instead'); - }, - 'util': util -}; - -/** - * load jsoneditor.css - */ -var loadCss = function () { - // find the script named 'jsoneditor.js' or 'jsoneditor-min.js' or - // 'jsoneditor.min.js', and use its path to find the css file to be - // loaded. - var scripts = document.getElementsByTagName('script'); - for (var s = 0; s < scripts.length; s++) { - var src = scripts[s].src; - if (/(^|\/)jsoneditor([-\.]min)?.js$/.test(src)) { - var jsFile = src.split('?')[0]; - var cssFile = jsFile.substring(0, jsFile.length - 2) + 'css'; - - // load css file - var link = document.createElement('link'); - link.type = 'text/css'; - link.rel = 'stylesheet'; - link.href = cssFile; - document.getElementsByTagName('head')[0].appendChild(link); - - break; - } - } -}; - -/** - * CommonJS module exports - */ -if (typeof(module) != 'undefined' && typeof(exports) != 'undefined') { - loadCss(); - module.exports = exports = jsoneditor; -} - -/** - * AMD module exports - */ -if (typeof(require) != 'undefined' && typeof(define) != 'undefined') { - loadCss(); - define(function () { - return jsoneditor; - }); -} -else { - // attach the module to the window, load as a regular javascript file - window['jsoneditor'] = jsoneditor; -} - - -})(); diff --git a/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/README.md b/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/README.md deleted file mode 100644 index e31e1906..00000000 --- a/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/README.md +++ /dev/null @@ -1,62 +0,0 @@ -JSON Lint -========= - -A pure [JavaScript version](http://zaach.github.com/jsonlint/) of the service provided at [jsonlint.com](http://jsonlint.com). - -## Command line interface -Install jsonlint with npm to use the command line interface: - - npm install jsonlint -g - -Validate a file like so: - - jsonlint myfile.json - -or pipe input into stdin: - - cat myfile.json | jsonlint - -jsonlint will either report a syntax error with details or pretty print the source if it is valid. - -### Options - - $ jsonlint -h - - usage: jsonlint [options] - - file file to parse; otherwise uses stdin - - options: - -v, --version print version and exit - -s, --sort-keys sort object keys - -i, --in-place overwrite the file - -t CHAR, --indent CHAR character(s) to use for indentation - -c, --compact compact error display - -V, --validate a JSON schema to use for validation - -e, --environment which specification of JSON Schema the validation file uses - - -## Module interface - -I'm not sure why you wouldn't use the built in `JSON.parse` but you can use jsonlint from a CommonJS module: - - var jsonlint = require("jsonlint"); - - jsonlint.parse('{"creative?": false}'); - -It returns the parsed object or throws an `Error`. - -## Vim Plugins - -* [Syntastic](http://www.vim.org/scripts/script.php?script_id=2736) -* [sourcebeautify](http://www.vim.org/scripts/script.php?script_id=4079) - -## MIT License - -Copyright (C) 2012 Zachary Carter - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/jsonlint.js b/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/jsonlint.js deleted file mode 100644 index 598c18c2..00000000 --- a/Bench4Q-Web/src/main/webapp/js/lib/jsonlint/jsonlint.js +++ /dev/null @@ -1,432 +0,0 @@ -/* Jison generated parser */ -var jsonlint = (function(){ -var parser = {trace: function trace() { }, -yy: {}, -symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1}, -terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"}, -productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]], -performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) { - -var $0 = $$.length - 1; -switch (yystate) { -case 1: // replace escaped characters with actual character - this.$ = yytext.replace(/\\(\\|")/g, "$"+"1") - .replace(/\\n/g,'\n') - .replace(/\\r/g,'\r') - .replace(/\\t/g,'\t') - .replace(/\\v/g,'\v') - .replace(/\\f/g,'\f') - .replace(/\\b/g,'\b'); - -break; -case 2:this.$ = Number(yytext); -break; -case 3:this.$ = null; -break; -case 4:this.$ = true; -break; -case 5:this.$ = false; -break; -case 6:return this.$ = $$[$0-1]; -break; -case 13:this.$ = {}; -break; -case 14:this.$ = $$[$0-1]; -break; -case 15:this.$ = [$$[$0-2], $$[$0]]; -break; -case 16:this.$ = {}; this.$[$$[$0][0]] = $$[$0][1]; -break; -case 17:this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1]; -break; -case 18:this.$ = []; -break; -case 19:this.$ = $$[$0-1]; -break; -case 20:this.$ = [$$[$0]]; -break; -case 21:this.$ = $$[$0-2]; $$[$0-2].push($$[$0]); -break; -} -}, -table: [{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],12:1,13:2,15:7,16:8,17:[1,14],23:[1,15]},{1:[3]},{14:[1,16]},{14:[2,7],18:[2,7],22:[2,7],24:[2,7]},{14:[2,8],18:[2,8],22:[2,8],24:[2,8]},{14:[2,9],18:[2,9],22:[2,9],24:[2,9]},{14:[2,10],18:[2,10],22:[2,10],24:[2,10]},{14:[2,11],18:[2,11],22:[2,11],24:[2,11]},{14:[2,12],18:[2,12],22:[2,12],24:[2,12]},{14:[2,3],18:[2,3],22:[2,3],24:[2,3]},{14:[2,4],18:[2,4],22:[2,4],24:[2,4]},{14:[2,5],18:[2,5],22:[2,5],24:[2,5]},{14:[2,1],18:[2,1],21:[2,1],22:[2,1],24:[2,1]},{14:[2,2],18:[2,2],22:[2,2],24:[2,2]},{3:20,4:[1,12],18:[1,17],19:18,20:19},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:23,15:7,16:8,17:[1,14],23:[1,15],24:[1,21],25:22},{1:[2,6]},{14:[2,13],18:[2,13],22:[2,13],24:[2,13]},{18:[1,24],22:[1,25]},{18:[2,16],22:[2,16]},{21:[1,26]},{14:[2,18],18:[2,18],22:[2,18],24:[2,18]},{22:[1,28],24:[1,27]},{22:[2,20],24:[2,20]},{14:[2,14],18:[2,14],22:[2,14],24:[2,14]},{3:20,4:[1,12],20:29},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:30,15:7,16:8,17:[1,14],23:[1,15]},{14:[2,19],18:[2,19],22:[2,19],24:[2,19]},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:31,15:7,16:8,17:[1,14],23:[1,15]},{18:[2,17],22:[2,17]},{18:[2,15],22:[2,15]},{22:[2,21],24:[2,21]}], -defaultActions: {16:[2,6]}, -parseError: function parseError(str, hash) { - throw new Error(str); -}, -parse: function parse(input) { - var self = this, - stack = [0], - vstack = [null], // semantic value stack - lstack = [], // location stack - table = this.table, - yytext = '', - yylineno = 0, - yyleng = 0, - recovering = 0, - TERROR = 2, - EOF = 1; - - //this.reductionCount = this.shiftCount = 0; - - this.lexer.setInput(input); - this.lexer.yy = this.yy; - this.yy.lexer = this.lexer; - if (typeof this.lexer.yylloc == 'undefined') - this.lexer.yylloc = {}; - var yyloc = this.lexer.yylloc; - lstack.push(yyloc); - - if (typeof this.yy.parseError === 'function') - this.parseError = this.yy.parseError; - - function popStack (n) { - stack.length = stack.length - 2*n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - - function lex() { - var token; - token = self.lexer.lex() || 1; // $end = 1 - // if token isn't its numeric value, convert - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - } - - var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected; - while (true) { - // retreive state number from top of stack - state = stack[stack.length-1]; - - // use default actions if available - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol == null) - symbol = lex(); - // read action for current state and first input - action = table[state] && table[state][symbol]; - } - - // handle parse error - _handle_error: - if (typeof action === 'undefined' || !action.length || !action[0]) { - - if (!recovering) { - // Report error - expected = []; - for (p in table[state]) if (this.terminals_[p] && p > 2) { - expected.push("'"+this.terminals_[p]+"'"); - } - var errStr = ''; - if (this.lexer.showPosition) { - errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'"; - } else { - errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " + - (symbol == 1 /*EOF*/ ? "end of input" : - ("'"+(this.terminals_[symbol] || symbol)+"'")); - } - this.parseError(errStr, - {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); - } - - // just recovered from another error - if (recovering == 3) { - if (symbol == EOF) { - throw new Error(errStr || 'Parsing halted.'); - } - - // discard current lookahead and grab another - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - symbol = lex(); - } - - // try to recover from error - while (1) { - // check for error recovery rule in this state - if ((TERROR.toString()) in table[state]) { - break; - } - if (state == 0) { - throw new Error(errStr || 'Parsing halted.'); - } - popStack(1); - state = stack[stack.length-1]; - } - - preErrorSymbol = symbol; // save the lookahead token - symbol = TERROR; // insert generic error symbol as new lookahead - state = stack[stack.length-1]; - action = table[state] && table[state][TERROR]; - recovering = 3; // allow 3 real symbols to be shifted before reporting a new error - } - - // this shouldn't happen, unless resolve defaults are off - if (action[0] instanceof Array && action.length > 1) { - throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol); - } - - switch (action[0]) { - - case 1: // shift - //this.shiftCount++; - - stack.push(symbol); - vstack.push(this.lexer.yytext); - lstack.push(this.lexer.yylloc); - stack.push(action[1]); // push state - symbol = null; - if (!preErrorSymbol) { // normal execution/no error - yyleng = this.lexer.yyleng; - yytext = this.lexer.yytext; - yylineno = this.lexer.yylineno; - yyloc = this.lexer.yylloc; - if (recovering > 0) - recovering--; - } else { // error just occurred, resume old lookahead f/ before error - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - - case 2: // reduce - //this.reductionCount++; - - len = this.productions_[action[1]][1]; - - // perform semantic action - yyval.$ = vstack[vstack.length-len]; // default to $$ = $1 - // default location, uses first token for firsts, last for lasts - yyval._$ = { - first_line: lstack[lstack.length-(len||1)].first_line, - last_line: lstack[lstack.length-1].last_line, - first_column: lstack[lstack.length-(len||1)].first_column, - last_column: lstack[lstack.length-1].last_column - }; - r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); - - if (typeof r !== 'undefined') { - return r; - } - - // pop off stack - if (len) { - stack = stack.slice(0,-1*len*2); - vstack = vstack.slice(0, -1*len); - lstack = lstack.slice(0, -1*len); - } - - stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) - vstack.push(yyval.$); - lstack.push(yyval._$); - // goto new state = table[STATE][NONTERMINAL] - newState = table[stack[stack.length-2]][stack[stack.length-1]]; - stack.push(newState); - break; - - case 3: // accept - return true; - } - - } - - return true; -}}; -/* Jison generated lexer */ -var lexer = (function(){ -var lexer = ({EOF:1, -parseError:function parseError(str, hash) { - if (this.yy.parseError) { - this.yy.parseError(str, hash); - } else { - throw new Error(str); - } - }, -setInput:function (input) { - this._input = input; - this._more = this._less = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; - return this; - }, -input:function () { - var ch = this._input[0]; - this.yytext+=ch; - this.yyleng++; - this.match+=ch; - this.matched+=ch; - var lines = ch.match(/\n/); - if (lines) this.yylineno++; - this._input = this._input.slice(1); - return ch; - }, -unput:function (ch) { - this._input = ch + this._input; - return this; - }, -more:function () { - this._more = true; - return this; - }, -less:function (n) { - this._input = this.match.slice(n) + this._input; - }, -pastInput:function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); - }, -upcomingInput:function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20-next.length); - } - return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); - }, -showPosition:function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c+"^"; - }, -next:function () { - if (this.done) { - return this.EOF; - } - if (!this._input) this.done = true; - - var token, - match, - tempMatch, - index, - col, - lines; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i=0;i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (!this.options.flex) break; - } - } - if (match) { - lines = match[0].match(/\n.*/g); - if (lines) this.yylineno += lines.length; - this.yylloc = {first_line: this.yylloc.last_line, - last_line: this.yylineno+1, - first_column: this.yylloc.last_column, - last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length} - this.yytext += match[0]; - this.match += match[0]; - this.yyleng = this.yytext.length; - this._more = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); - if (this.done && this._input) this.done = false; - if (token) return token; - else return; - } - if (this._input === "") { - return this.EOF; - } else { - this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), - {text: "", token: null, line: this.yylineno}); - } - }, -lex:function lex() { - var r = this.next(); - if (typeof r !== 'undefined') { - return r; - } else { - return this.lex(); - } - }, -begin:function begin(condition) { - this.conditionStack.push(condition); - }, -popState:function popState() { - return this.conditionStack.pop(); - }, -_currentRules:function _currentRules() { - return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; - }, -topState:function () { - return this.conditionStack[this.conditionStack.length-2]; - }, -pushState:function begin(condition) { - this.begin(condition); - }}); -lexer.options = {}; -lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { - -var YYSTATE=YY_START -switch($avoiding_name_collisions) { -case 0:/* skip whitespace */ -break; -case 1:return 6 -break; -case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4 -break; -case 3:return 17 -break; -case 4:return 18 -break; -case 5:return 23 -break; -case 6:return 24 -break; -case 7:return 22 -break; -case 8:return 21 -break; -case 9:return 10 -break; -case 10:return 11 -break; -case 11:return 8 -break; -case 12:return 14 -break; -case 13:return 'INVALID' -break; -} -}; -lexer.rules = [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/]; -lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}; - - -; -return lexer;})() -parser.lexer = lexer; -return parser; -})(); -if (typeof require !== 'undefined' && typeof exports !== 'undefined') { -exports.parser = jsonlint; -exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); } -exports.main = function commonjsMain(args) { - if (!args[1]) - throw new Error('Usage: '+args[0]+' FILE'); - if (typeof process !== 'undefined') { - var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8"); - } else { - var cwd = require("file").path(require("file").cwd()); - var source = cwd.join(args[1]).read({charset: "utf-8"}); - } - return exports.parser.parse(source); -} -if (typeof module !== 'undefined' && require.main === module) { - exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args); -} -} \ No newline at end of file diff --git a/Bench4Q-Web/src/main/webapp/js/theme.js b/Bench4Q-Web/src/main/webapp/js/theme.js index 12eeb399..fe534b28 100644 --- a/Bench4Q-Web/src/main/webapp/js/theme.js +++ b/Bench4Q-Web/src/main/webapp/js/theme.js @@ -1,24 +1,28 @@ -var current_theme = $.cookie('current_theme')==null ? 'cerulean' :$.cookie('current_theme'); -$(document).ready(function(){ - //themes, change CSS with JS - //default theme(CSS) is cerulean, change it if needed - - switch_theme(current_theme); - - $('#themes a[data-value="'+current_theme+'"]').find('i').addClass('icon-ok'); - - $('#themes a').click(function(e){ - e.preventDefault(); - current_theme=$(this).attr('data-value'); - $.cookie('current_theme',current_theme,{expires:365}); - switch_theme(current_theme); - $('#themes i').removeClass('icon-ok'); - $(this).find('i').addClass('icon-ok'); - }); - - - function switch_theme(theme_name) - { - $('#bs-css').attr('href','css/bootstrap-'+theme_name+'.css'); - } -}); \ No newline at end of file +var current_theme = $.cookie('current_theme') == null ? 'cerulean' : $ + .cookie('current_theme'); +$(document).ready( + function() { + // themes, change CSS with JS + // default theme(CSS) is cerulean, change it if needed + + switch_theme(current_theme); + + $('#themes a[data-value="' + current_theme + '"]').find('i') + .addClass('icon-ok'); + + $('#themes a').click(function(e) { + e.preventDefault(); + current_theme = $(this).attr('data-value'); + $.cookie('current_theme', current_theme, { + expires : 365 + }); + switch_theme(current_theme); + $('#themes i').removeClass('icon-ok'); + $(this).find('i').addClass('icon-ok'); + }); + + function switch_theme(theme_name) { + $('#bs-css').attr('href', + '../css/bootstrap-' + theme_name + '.css'); + } + }); \ No newline at end of file diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/ace.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/ace.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/ace.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/ace.js diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/ext-searchbox.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/ext-searchbox.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/ext-searchbox.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/ext-searchbox.js diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/mode-json.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/mode-json.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/mode-json.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/mode-json.js diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/theme-jsoneditor.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/theme-jsoneditor.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/theme-jsoneditor.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/theme-jsoneditor.js diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/theme-textmate.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/theme-textmate.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/theme-textmate.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/theme-textmate.js diff --git a/Bench4Q-Web/src/main/webapp/js/lib/ace/worker-json.js b/Bench4Q-Web/src/main/webapp/lib/ace/js/worker-json.js similarity index 100% rename from Bench4Q-Web/src/main/webapp/js/lib/ace/worker-json.js rename to Bench4Q-Web/src/main/webapp/lib/ace/js/worker-json.js diff --git a/Bench4Q-Web/src/main/webapp/lib/bootstrap/css/bootstrap-cerulean.css b/Bench4Q-Web/src/main/webapp/lib/bootstrap/css/bootstrap-cerulean.css new file mode 100644 index 00000000..df7a72cd --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/bootstrap/css/bootstrap-cerulean.css @@ -0,0 +1,4454 @@ +@import url(http://fonts.googleapis.com/css?family=Karla|Ubuntu); +/*! + * Bootstrap v2.0.4 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} +body { + margin: 0; + font-family: "Ubuntu", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; + color: #555555; + background-color: #ffffff; + text-shadow:0 -1px 1px rgba(0, 0, 0, 0.2) +} +a { + color: #369bd7; + text-decoration: none; +} +a:hover { + color: #2071a1; + text-decoration: underline; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + margin-left: 20px; +} +.container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.127659574%; + *margin-left: 2.0744680846382977%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .span12 { + width: 99.99999998999999%; + *width: 99.94680850063828%; +} +.row-fluid .span11 { + width: 91.489361693%; + *width: 91.4361702036383%; +} +.row-fluid .span10 { + width: 82.97872339599999%; + *width: 82.92553190663828%; +} +.row-fluid .span9 { + width: 74.468085099%; + *width: 74.4148936096383%; +} +.row-fluid .span8 { + width: 65.95744680199999%; + *width: 65.90425531263828%; +} +.row-fluid .span7 { + width: 57.446808505%; + *width: 57.3936170156383%; +} +.row-fluid .span6 { + width: 48.93617020799999%; + *width: 48.88297871863829%; +} +.row-fluid .span5 { + width: 40.425531911%; + *width: 40.3723404216383%; +} +.row-fluid .span4 { + width: 31.914893614%; + *width: 31.8617021246383%; +} +.row-fluid .span3 { + width: 23.404255317%; + *width: 23.3510638276383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.8404255306383%; +} +.row-fluid .span1 { + width: 6.382978723%; + *width: 6.329787233638298%; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; +} +p small { + font-size: 11px; + color: #999999; +} +.lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + font-family: 'Karla', sans-serif; + font-weight: bold; + color: #317eac; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + color: #999999; +} +h1 { + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 18px; +} +h3 { + font-size: 18px; + line-height: 27px; +} +h3 small { + font-size: 14px; +} +h4, +h5, +h6 { + line-height: 18px; +} +h4 { + font-size: 14px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: #999999; + text-transform: uppercase; +} +.page-header { + padding-bottom: 17px; + margin: 18px 0; + border-bottom: 1px solid #f5f5f5; +} +.page-header h1 { + line-height: 1; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; + line-height: 17px; +} +dd { + margin-left: 9px; +} +.dl-horizontal dt { + float: left; + width: 120px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 130px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #f5f5f5; + border-bottom: 1px solid #ffffff; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: #999999; +} +abbr[title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #f5f5f5; +} +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 22.5px; +} +blockquote small { + display: block; + line-height: 18px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #f5f5f5; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +small { + font-size: 100%; +} +cite { + font-style: normal; +} +code, +pre { + padding: 0 3px 2px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12.025px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 27px; + font-size: 19.5px; + line-height: 36px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555555; +} +input, +textarea { + width: 210px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 3px 0; + *margin-top: 0; + /* IE7 */ + + line-height: normal; + cursor: pointer; +} +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +.uneditable-textarea { + width: auto; + height: auto; +} +select, +input[type="file"] { + height: 28px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #bbb; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +input.span12, textarea.span12, .uneditable-input.span12 { + width: 930px; +} +input.span11, textarea.span11, .uneditable-input.span11 { + width: 850px; +} +input.span10, textarea.span10, .uneditable-input.span10 { + width: 770px; +} +input.span9, textarea.span9, .uneditable-input.span9 { + width: 690px; +} +input.span8, textarea.span8, .uneditable-input.span8 { + width: 610px; +} +input.span7, textarea.span7, .uneditable-input.span7 { + width: 530px; +} +input.span6, textarea.span6, .uneditable-input.span6 { + width: 450px; +} +input.span5, textarea.span5, .uneditable-input.span5 { + width: 370px; +} +input.span4, textarea.span4, .uneditable-input.span4 { + width: 290px; +} +input.span3, textarea.span3, .uneditable-input.span3 { + width: 210px; +} +input.span2, textarea.span2, .uneditable-input.span2 { + width: 130px; +} +input.span1, textarea.span1, .uneditable-input.span1 { + width: 50px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #f5f5f5; + border-color: #ddd; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning > label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #1c628b; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #1c628b; + border-color: #1c628b; +} +.control-group.warning .checkbox:focus, +.control-group.warning .radio:focus, +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #134461; + -webkit-box-shadow: 0 0 6px #369bd7; + -moz-box-shadow: 0 0 6px #369bd7; + box-shadow: 0 0 6px #369bd7; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #1c628b; + background-color: #8bc5e8; + border-color: #1c628b; +} +.control-group.error > label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #bd4247; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #bd4247; + border-color: #bd4247; +} +.control-group.error .checkbox:focus, +.control-group.error .radio:focus, +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #983538; + -webkit-box-shadow: 0 0 6px #d88e90; + -moz-box-shadow: 0 0 6px #d88e90; + box-shadow: 0 0 6px #d88e90; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #bd4247; + background-color: #eddbe3; + border-color: #bd4247; +} +.control-group.success > label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #669533; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #669533; + border-color: #669533; +} +.control-group.success .checkbox:focus, +.control-group.success .radio:focus, +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #4c6f26; + -webkit-box-shadow: 0 0 6px #99ca63; + -moz-box-shadow: 0 0 6px #99ca63; + box-shadow: 0 0 6px #99ca63; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #669533; + background-color: #ccddbb; + border-color: #669533; +} +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; +} +.form-actions:after { + clear: both; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; + cursor: not-allowed; + background-color: #ffffff; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} +:-moz-placeholder { + color: #999999; +} +:-ms-input-placeholder { + color: #999999; +} +::-webkit-input-placeholder { + color: #999999; +} +.help-block, +.help-inline { + color: #555555; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-prepend, +.input-append { + margin-bottom: 5px; +} +.input-prepend input, +.input-append input, +.input-prepend select, +.input-append select, +.input-prepend .uneditable-input, +.input-append .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: middle; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend input:focus, +.input-append input:focus, +.input-prepend select:focus, +.input-append select:focus, +.input-prepend .uneditable-input:focus, +.input-append .uneditable-input:focus { + z-index: 2; +} +.input-prepend .uneditable-input, +.input-append .uneditable-input { + border-left-color: #ccc; +} +.input-prepend .add-on, +.input-append .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #f5f5f5; + border: 1px solid #ccc; +} +.input-prepend .add-on, +.input-append .add-on, +.input-prepend .btn, +.input-append .btn { + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .active, +.input-append .active { + background-color: #bede9c; + border-color: #73a839; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .uneditable-input { + border-right-color: #ccc; + border-left-color: #eee; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 14px; + -moz-border-radius: 14px; + border-radius: 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 0; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 160px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 160px; +} +.form-horizontal .help-block { + margin-top: 9px; + margin-bottom: 0; +} +.form-horizontal .form-actions { + padding-left: 160px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapsed; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.table tbody tr:hover td, +.table tbody tr:hover th { + background-color: #f5f5f5; +} +table .span1 { + float: none; + width: 44px; + margin-left: 0; +} +table .span2 { + float: none; + width: 124px; + margin-left: 0; +} +table .span3 { + float: none; + width: 204px; + margin-left: 0; +} +table .span4 { + float: none; + width: 284px; + margin-left: 0; +} +table .span5 { + float: none; + width: 364px; + margin-left: 0; +} +table .span6 { + float: none; + width: 444px; + margin-left: 0; +} +table .span7 { + float: none; + width: 524px; + margin-left: 0; +} +table .span8 { + float: none; + width: 604px; + margin-left: 0; +} +table .span9 { + float: none; + width: 684px; + margin-left: 0; +} +table .span10 { + float: none; + width: 764px; + margin-left: 0; +} +table .span11 { + float: none; + width: 844px; + margin-left: 0; +} +table .span12 { + float: none; + width: 924px; + margin-left: 0; +} +table .span13 { + float: none; + width: 1004px; + margin-left: 0; +} +table .span14 { + float: none; + width: 1084px; + margin-left: 0; +} +table .span15 { + float: none; + width: 1164px; + margin-left: 0; +} +table .span16 { + float: none; + width: 1244px; + margin-left: 0; +} +table .span17 { + float: none; + width: 1324px; + margin-left: 0; +} +table .span18 { + float: none; + width: 1404px; + margin-left: 0; +} +table .span19 { + float: none; + width: 1484px; + margin-left: 0; +} +table .span20 { + float: none; + width: 1564px; + margin-left: 0; +} +table .span21 { + float: none; + width: 1644px; + margin-left: 0; +} +table .span22 { + float: none; + width: 1724px; + margin-left: 0; +} +table .span23 { + float: none; + width: 1804px; + margin-left: 0; +} +table .span24 { + float: none; + width: 1884px; + margin-left: 0; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} +[class^="icon-"]:last-child, +[class*=" icon-"]:last-child { + *margin-left: 0; +} +.icon-white { + background-image: url("../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; +} +.icon-folder-open { + background-position: -408px -120px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; + opacity: 0.3; + filter: alpha(opacity=30); +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 4px 0; + margin: 1px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #369bd7; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: "\2191"; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -ms-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -ms-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + *line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(top, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} +.btn-small { + padding: 5px 9px; + font-size: 11px; + line-height: 16px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 2px 6px; + font-size: 11px; + line-height: 14px; +} +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn { + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn-primary { + background-color: #368bd7; + background-image: -moz-linear-gradient(top, #369bd7, #3673d7); + background-image: -ms-linear-gradient(top, #369bd7, #3673d7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#369bd7), to(#3673d7)); + background-image: -webkit-linear-gradient(top, #369bd7, #3673d7); + background-image: -o-linear-gradient(top, #369bd7, #3673d7); + background-image: linear-gradient(top, #369bd7, #3673d7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#369bd7', endColorstr='#3673d7', GradientType=0); + border-color: #3673d7 #3673d7 #2050a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #3673d7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #3673d7; + *background-color: #2866cb; +} +.btn-primary:active, +.btn-primary.active { + background-color: #245bb6 \9; +} +.btn-warning { + background-color: #dd5600; + background-image: -moz-linear-gradient(top, #dd5600, #dd5600); + background-image: -ms-linear-gradient(top, #dd5600, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd5600), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #dd5600, #dd5600); + background-image: -o-linear-gradient(top, #dd5600, #dd5600); + background-image: linear-gradient(top, #dd5600, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd5600', endColorstr='#dd5600', GradientType=0); + border-color: #dd5600 #dd5600 #913800; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #dd5600; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #dd5600; + *background-color: #c44c00; +} +.btn-warning:active, +.btn-warning.active { + background-color: #aa4200 \9; +} +.btn-danger { + background-color: #c32627; + background-image: -moz-linear-gradient(top, #c71c22, #bd362f); + background-image: -ms-linear-gradient(top, #c71c22, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#c71c22), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #c71c22, #bd362f); + background-image: -o-linear-gradient(top, #c71c22, #bd362f); + background-image: linear-gradient(top, #c71c22, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c71c22', endColorstr='#bd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + background-color: #65a643; + background-image: -moz-linear-gradient(top, #73a839, #51a351); + background-image: -ms-linear-gradient(top, #73a839, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#73a839), to(#51a351)); + background-image: -webkit-linear-gradient(top, #73a839, #51a351); + background-image: -o-linear-gradient(top, #73a839, #51a351); + background-image: linear-gradient(top, #73a839, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#73a839', endColorstr='#51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + background-color: #6d76b3; + background-image: -moz-linear-gradient(top, #9760b3, #2f96b4); + background-image: -ms-linear-gradient(top, #9760b3, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#9760b3), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #9760b3, #2f96b4); + background-image: -o-linear-gradient(top, #9760b3, #2f96b4); + background-image: linear-gradient(top, #9760b3, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9760b3', endColorstr='#2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + background-color: #a27a28; + background-image: -moz-linear-gradient(top, #f7b42c, #222222); + background-image: -ms-linear-gradient(top, #f7b42c, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f7b42c), to(#222222)); + background-image: -webkit-linear-gradient(top, #f7b42c, #222222); + background-image: -o-linear-gradient(top, #f7b42c, #222222); + background-image: linear-gradient(top, #f7b42c, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7b42c', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, +.btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-mini.dropdown-toggle { + padding-left: 5px; + padding-right: 5px; +} +.btn-group > .btn-small.dropdown-toggle { + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-large.dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #3673d7; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #dd5600; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-mini .caret { + margin-top: 5px; +} +.btn-small .caret { + margin-top: 6px; +} +.btn-large .caret { + margin-top: 6px; + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.dropup .btn-large .caret { + border-bottom: 5px solid #000000; + border-top: 0; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #8bc5e8; + border: 1px solid #7ed0e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #1c628b; +} +.alert-heading { + color: inherit; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #ccddbb; + border-color: #c6d4aa; + color: #669533; +} +.alert-danger, +.alert-error { + background-color: #eddbe3; + border-color: #e8d1df; + color: #bd4247; +} +.alert-info { + background-color: #edebe1; + border-color: #e0d9cb; + color: #817b58; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.nav > .pull-right { + float: right; +} +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #369bd7; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover { + color: #ffffff; + background-color: #369bd7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: #369bd7; + border-bottom-color: #369bd7; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: #2071a1; + border-bottom-color: #2071a1; +} +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.nav > .dropdown.active > a:hover { + color: #000000; + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #dddddd #f5f5f5 #f5f5f5; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #f5f5f5 #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.navbar { + *position: relative; + *z-index: 2; + overflow: visible; + margin-bottom: 18px; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #50a8dc; + background-image: -moz-linear-gradient(top, #61b0df, #369bd7); + background-image: -ms-linear-gradient(top, #61b0df, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#61b0df), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #61b0df, #369bd7); + background-image: -o-linear-gradient(top, #61b0df, #369bd7); + background-image: linear-gradient(top, #61b0df, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#61b0df', endColorstr='#369bd7', GradientType=0); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; +} +.navbar { + color: #f5f5f5; +} +.navbar .brand:hover { + text-decoration: none; +} +.navbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + line-height: 1; + color: #f5f5f5; +} +.navbar .navbar-text { + margin-bottom: 0; + line-height: 40px; +} +.navbar .navbar-link { + color: #f5f5f5; +} +.navbar .navbar-link:hover { + color: #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn { + margin: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; +} +.navbar-search .search-query { + padding: 4px 9px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #ffffff; + background-color: #a0d0ec; + border: 1px solid #288ecb; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.navbar-search .search-query:-moz-placeholder { + color: #ffffff; +} +.navbar-search .search-query:-ms-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query::-webkit-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query:focus, +.navbar-search .search-query.focused { + padding: 5px 10px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; +} +.navbar .nav > li { + display: block; + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9px 10px 11px; + line-height: 19px; + color: #f5f5f5; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-right: 1px solid #3887B3; + border-left: 1px solid #3887B3; +} +.navbar .btn { + display: inline-block; + padding: 4px 10px 4px; + margin: 5px 5px 6px; + line-height: 18px; +} +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} +.navbar .nav > li > a:hover { + background-color: transparent; + color: #ffffff; + text-decoration: none; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: rgba(0, 0, 0, 0.2); +} +.navbar .divider-vertical { + height: 40px; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: #369bd7; + border-right: 1px solid #61b0df; +} +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #50a8dc; + background-image: -moz-linear-gradient(top, #61b0df, #369bd7); + background-image: -ms-linear-gradient(top, #61b0df, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#61b0df), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #61b0df, #369bd7); + background-image: -o-linear-gradient(top, #61b0df, #369bd7); + background-image: linear-gradient(top, #61b0df, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#61b0df', endColorstr='#369bd7', GradientType=0); + border-color: #369bd7 #369bd7 #2071a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #369bd7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + background-color: #369bd7; + *background-color: #288ecb; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #2480b6 \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown .dropdown-toggle .caret, +.navbar .nav li.dropdown.open .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar .nav li.dropdown.active .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: transparent; +} +.navbar .nav li.dropdown.active > .dropdown-toggle:hover { + color: #ffffff; +} +.navbar .pull-right .dropdown-menu, +.navbar .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right .dropdown-menu:before, +.navbar .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right .dropdown-menu:after, +.navbar .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + list-style: none; + background-color: #fbfbfb; + background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); + background-image: linear-gradient(top, #ffffff, #f5f5f5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} +.breadcrumb li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb .divider { + padding: 0 5px; + color: #999999; +} +.breadcrumb .active a { + color: #333333; +} +.pagination { + height: 36px; + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination li { + display: inline; +} +.pagination a { + float: left; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: #999999; + cursor: default; +} +.pagination .disabled span, +.pagination .disabled a, +.pagination .disabled a:hover { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination li:last-child a { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pager { + margin-left: 0; + margin-bottom: 18px; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} +.pager .disabled a, +.pager .disabled a:hover { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2060; +} +.modal-open .tooltip { + z-index: 2070; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -ms-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); +} +a.thumbnail:hover { + border-color: #369bd7; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} +.label, +.badge { + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + padding: 1px 4px 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding: 1px 9px 2px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +a.label:hover, +a.badge:hover { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #bd4247; +} +.label-important[href], +.badge-important[href] { + background-color: #983538; +} +.label-warning, +.badge-warning { + background-color: #dd5600; +} +.label-warning[href], +.badge-warning[href] { + background-color: #aa4200; +} +.label-success, +.badge-success { + background-color: #669533; +} +.label-success[href], +.badge-success[href] { + background-color: #4c6f26; +} +.label-info, +.badge-info { + background-color: #817b58; +} +.label-info[href], +.badge-info[href] { + background-color: #625e43; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(top, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 18px; + color: #ffffff; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -ms-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(top, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -ms-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); +} +.progress-danger.progress-striped .bar { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); +} +.progress-success.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); +} +.progress-info.progress-striped .bar { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar { + background-color: #f16e1a; + background-image: -moz-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -ms-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff7d2b), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -o-linear-gradient(top, #ff7d2b, #dd5600); + background-image: linear-gradient(top, #ff7d2b, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff7d2b', endColorstr='#dd5600', GradientType=0); +} +.progress-warning.progress-striped .bar { + background-color: #ff7d2b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel .item > img { + display: block; + line-height: 1; +} +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} +.carousel .active { + left: 0; +} +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel .next { + left: 100%; +} +.carousel .prev { + left: -100%; +} +.carousel .next.left, +.carousel .prev.right { + left: 0; +} +.carousel .active.left { + left: -100%; +} +.carousel .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #f5f5f5; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit p { + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.navbar,.top-block { + font-family: 'Karla', sans-serif; +} +.navbar .navbar-inner { + background-color: #3f9fd9; +} +.navbar-inner{ + background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(0,0,0,0.15) 50%, rgba(30,30,30,0) 100%); +background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(50%,rgba(0,0,0,0.15)), color-stop(100%,rgba(30,30,30,0))); +background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: -o-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#001e1e1e',GradientType=0 ); +} +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.active.open > .dropdown-toggle { + background-color: rgba(0, 0, 0, 0.2); +} +.navbar .search-query { + border: 1px solid #2480b6; +} +.navbar .nav-collapse.in > .nav > li .dropdown-menu a { + color: #ffffff; +} +.navbar .nav-collapse.in > .nav > li .dropdown-menu a:hover { + color: #ffffff; +} +.navbar .nav-collapse.in .nav li > a { + color: #ffffff; +} +.navbar .nav-collapse.in .nav li > a:hover { + background-color: #2B7CAC; +} +.navbar .btn-navbar:hover { + background-color: #cccccc; +} +div.subnav { + font-family: 'Karla', sans-serif; +} +.btn { + background-color: #ffffff; + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(5%, #ffffff), to(#ffffff)); + background-image: -webkit-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: -moz-linear-gradient(top, #ffffff, #ffffff 5%, #ffffff); + background-image: -ms-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: -o-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-repeat: no-repeat; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ffffff', GradientType=0); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn:hover { + background-position: 0 0; +} +.btn-primary { + background-color: #43a1da; + background-image: -moz-linear-gradient(top, #4ba6db, #369bd7); + background-image: -ms-linear-gradient(top, #4ba6db, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#4ba6db), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #4ba6db, #369bd7); + background-image: -o-linear-gradient(top, #4ba6db, #369bd7); + background-image: linear-gradient(top, #4ba6db, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4ba6db', endColorstr='#369bd7', GradientType=0); + border-color: #369bd7 #369bd7 #2071a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #369bd7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #369bd7; + *background-color: #288ecb; +} +.btn-primary:active, +.btn-primary.active { + background-color: #2480b6 \9; +} +.btn-info { + background-color: #9e6ab8; + background-image: -moz-linear-gradient(top, #a271bb, #9760b3); + background-image: -ms-linear-gradient(top, #a271bb, #9760b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#a271bb), to(#9760b3)); + background-image: -webkit-linear-gradient(top, #a271bb, #9760b3); + background-image: -o-linear-gradient(top, #a271bb, #9760b3); + background-image: linear-gradient(top, #a271bb, #9760b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#a271bb', endColorstr='#9760b3', GradientType=0); + border-color: #9760b3 #9760b3 #6f4086; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #9760b3; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #9760b3; + *background-color: #8b51a9; +} +.btn-info:active, +.btn-info.active { + background-color: #7d4898 \9; +} +.btn-success { + background-color: #7bb33d; + background-image: -moz-linear-gradient(top, #80bb3f, #73a839); + background-image: -ms-linear-gradient(top, #80bb3f, #73a839); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#80bb3f), to(#73a839)); + background-image: -webkit-linear-gradient(top, #80bb3f, #73a839); + background-image: -o-linear-gradient(top, #80bb3f, #73a839); + background-image: linear-gradient(top, #80bb3f, #73a839); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80bb3f', endColorstr='#73a839', GradientType=0); + border-color: #73a839 #73a839 #4c6f26; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #73a839; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #73a839; + *background-color: #669533; +} +.btn-success:active, +.btn-success.active { + background-color: #59822c \9; +} +.btn-warning { + background-color: #ec5c00; + background-image: -moz-linear-gradient(top, #f76000, #dd5600); + background-image: -ms-linear-gradient(top, #f76000, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f76000), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #f76000, #dd5600); + background-image: -o-linear-gradient(top, #f76000, #dd5600); + background-image: linear-gradient(top, #f76000, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f76000', endColorstr='#dd5600', GradientType=0); + border-color: #dd5600 #dd5600 #913800; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #dd5600; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #dd5600; + *background-color: #c44c00; +} +.btn-warning:active, +.btn-warning.active { + background-color: #aa4200 \9; +} +.btn-danger { + background-color: #d41e24; + background-image: -moz-linear-gradient(top, #dd1f26, #c71c22); + background-image: -ms-linear-gradient(top, #dd1f26, #c71c22); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd1f26), to(#c71c22)); + background-image: -webkit-linear-gradient(top, #dd1f26, #c71c22); + background-image: -o-linear-gradient(top, #dd1f26, #c71c22); + background-image: linear-gradient(top, #dd1f26, #c71c22); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd1f26', endColorstr='#c71c22', GradientType=0); + border-color: #c71c22 #c71c22 #841317; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #c71c22; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #c71c22; + *background-color: #b1191e; +} +.btn-danger:active, +.btn-danger.active { + background-color: #9a161a \9; +} +.btn-inverse { + background-color: #f8b93b; + background-image: -moz-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -ms-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f8bd45), to(#f7b42c)); + background-image: -webkit-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -o-linear-gradient(top, #f8bd45, #f7b42c); + background-image: linear-gradient(top, #f8bd45, #f7b42c); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8bd45', endColorstr='#f7b42c', GradientType=0); + border-color: #f7b42c #f7b42c #cf8d08; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f7b42c; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #f7b42c; + *background-color: #f6ab13; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #e79e09 \9; +} +i[class^="icon-"] { + opacity: 0.8; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} diff --git a/Bench4Q-Web/src/main/webapp/lib/chrisma/css/bootstrap-cerulean.css b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/bootstrap-cerulean.css new file mode 100644 index 00000000..df7a72cd --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/bootstrap-cerulean.css @@ -0,0 +1,4454 @@ +@import url(http://fonts.googleapis.com/css?family=Karla|Ubuntu); +/*! + * Bootstrap v2.0.4 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; +} +body { + margin: 0; + font-family: "Ubuntu", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; + color: #555555; + background-color: #ffffff; + text-shadow:0 -1px 1px rgba(0, 0, 0, 0.2) +} +a { + color: #369bd7; + text-decoration: none; +} +a:hover { + color: #2071a1; + text-decoration: underline; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + margin-left: 20px; +} +.container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.127659574%; + *margin-left: 2.0744680846382977%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .span12 { + width: 99.99999998999999%; + *width: 99.94680850063828%; +} +.row-fluid .span11 { + width: 91.489361693%; + *width: 91.4361702036383%; +} +.row-fluid .span10 { + width: 82.97872339599999%; + *width: 82.92553190663828%; +} +.row-fluid .span9 { + width: 74.468085099%; + *width: 74.4148936096383%; +} +.row-fluid .span8 { + width: 65.95744680199999%; + *width: 65.90425531263828%; +} +.row-fluid .span7 { + width: 57.446808505%; + *width: 57.3936170156383%; +} +.row-fluid .span6 { + width: 48.93617020799999%; + *width: 48.88297871863829%; +} +.row-fluid .span5 { + width: 40.425531911%; + *width: 40.3723404216383%; +} +.row-fluid .span4 { + width: 31.914893614%; + *width: 31.8617021246383%; +} +.row-fluid .span3 { + width: 23.404255317%; + *width: 23.3510638276383%; +} +.row-fluid .span2 { + width: 14.89361702%; + *width: 14.8404255306383%; +} +.row-fluid .span1 { + width: 6.382978723%; + *width: 6.329787233638298%; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; +} +p small { + font-size: 11px; + color: #999999; +} +.lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + font-family: 'Karla', sans-serif; + font-weight: bold; + color: #317eac; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + color: #999999; +} +h1 { + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 18px; +} +h3 { + font-size: 18px; + line-height: 27px; +} +h3 small { + font-size: 14px; +} +h4, +h5, +h6 { + line-height: 18px; +} +h4 { + font-size: 14px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: #999999; + text-transform: uppercase; +} +.page-header { + padding-bottom: 17px; + margin: 18px 0; + border-bottom: 1px solid #f5f5f5; +} +.page-header h1 { + line-height: 1; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; + line-height: 17px; +} +dd { + margin-left: 9px; +} +.dl-horizontal dt { + float: left; + width: 120px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 130px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #f5f5f5; + border-bottom: 1px solid #ffffff; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: #999999; +} +abbr[title] { + cursor: help; + border-bottom: 1px dotted #999999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #f5f5f5; +} +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 22.5px; +} +blockquote small { + display: block; + line-height: 18px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #f5f5f5; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +small { + font-size: 100%; +} +cite { + font-style: normal; +} +code, +pre { + padding: 0 3px 2px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12.025px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 27px; + font-size: 19.5px; + line-height: 36px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555555; +} +input, +textarea { + width: 210px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 3px 0; + *margin-top: 0; + /* IE7 */ + + line-height: normal; + cursor: pointer; +} +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +.uneditable-textarea { + width: auto; + height: auto; +} +select, +input[type="file"] { + height: 28px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #bbb; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +input.span12, textarea.span12, .uneditable-input.span12 { + width: 930px; +} +input.span11, textarea.span11, .uneditable-input.span11 { + width: 850px; +} +input.span10, textarea.span10, .uneditable-input.span10 { + width: 770px; +} +input.span9, textarea.span9, .uneditable-input.span9 { + width: 690px; +} +input.span8, textarea.span8, .uneditable-input.span8 { + width: 610px; +} +input.span7, textarea.span7, .uneditable-input.span7 { + width: 530px; +} +input.span6, textarea.span6, .uneditable-input.span6 { + width: 450px; +} +input.span5, textarea.span5, .uneditable-input.span5 { + width: 370px; +} +input.span4, textarea.span4, .uneditable-input.span4 { + width: 290px; +} +input.span3, textarea.span3, .uneditable-input.span3 { + width: 210px; +} +input.span2, textarea.span2, .uneditable-input.span2 { + width: 130px; +} +input.span1, textarea.span1, .uneditable-input.span1 { + width: 50px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #f5f5f5; + border-color: #ddd; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning > label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #1c628b; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #1c628b; + border-color: #1c628b; +} +.control-group.warning .checkbox:focus, +.control-group.warning .radio:focus, +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #134461; + -webkit-box-shadow: 0 0 6px #369bd7; + -moz-box-shadow: 0 0 6px #369bd7; + box-shadow: 0 0 6px #369bd7; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #1c628b; + background-color: #8bc5e8; + border-color: #1c628b; +} +.control-group.error > label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #bd4247; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #bd4247; + border-color: #bd4247; +} +.control-group.error .checkbox:focus, +.control-group.error .radio:focus, +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #983538; + -webkit-box-shadow: 0 0 6px #d88e90; + -moz-box-shadow: 0 0 6px #d88e90; + box-shadow: 0 0 6px #d88e90; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #bd4247; + background-color: #eddbe3; + border-color: #bd4247; +} +.control-group.success > label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #669533; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #669533; + border-color: #669533; +} +.control-group.success .checkbox:focus, +.control-group.success .radio:focus, +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #4c6f26; + -webkit-box-shadow: 0 0 6px #99ca63; + -moz-box-shadow: 0 0 6px #99ca63; + box-shadow: 0 0 6px #99ca63; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #669533; + background-color: #ccddbb; + border-color: #669533; +} +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; +} +.form-actions:after { + clear: both; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; + cursor: not-allowed; + background-color: #ffffff; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} +:-moz-placeholder { + color: #999999; +} +:-ms-input-placeholder { + color: #999999; +} +::-webkit-input-placeholder { + color: #999999; +} +.help-block, +.help-inline { + color: #555555; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-prepend, +.input-append { + margin-bottom: 5px; +} +.input-prepend input, +.input-append input, +.input-prepend select, +.input-append select, +.input-prepend .uneditable-input, +.input-append .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: middle; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend input:focus, +.input-append input:focus, +.input-prepend select:focus, +.input-append select:focus, +.input-prepend .uneditable-input:focus, +.input-append .uneditable-input:focus { + z-index: 2; +} +.input-prepend .uneditable-input, +.input-append .uneditable-input { + border-left-color: #ccc; +} +.input-prepend .add-on, +.input-append .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #f5f5f5; + border: 1px solid #ccc; +} +.input-prepend .add-on, +.input-append .add-on, +.input-prepend .btn, +.input-append .btn { + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .active, +.input-append .active { + background-color: #bede9c; + border-color: #73a839; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .uneditable-input { + border-right-color: #ccc; + border-left-color: #eee; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 14px; + -moz-border-radius: 14px; + border-radius: 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 0; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 160px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 160px; +} +.form-horizontal .help-block { + margin-top: 9px; + margin-bottom: 0; +} +.form-horizontal .form-actions { + padding-left: 160px; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #dddddd; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapsed; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.table tbody tr:hover td, +.table tbody tr:hover th { + background-color: #f5f5f5; +} +table .span1 { + float: none; + width: 44px; + margin-left: 0; +} +table .span2 { + float: none; + width: 124px; + margin-left: 0; +} +table .span3 { + float: none; + width: 204px; + margin-left: 0; +} +table .span4 { + float: none; + width: 284px; + margin-left: 0; +} +table .span5 { + float: none; + width: 364px; + margin-left: 0; +} +table .span6 { + float: none; + width: 444px; + margin-left: 0; +} +table .span7 { + float: none; + width: 524px; + margin-left: 0; +} +table .span8 { + float: none; + width: 604px; + margin-left: 0; +} +table .span9 { + float: none; + width: 684px; + margin-left: 0; +} +table .span10 { + float: none; + width: 764px; + margin-left: 0; +} +table .span11 { + float: none; + width: 844px; + margin-left: 0; +} +table .span12 { + float: none; + width: 924px; + margin-left: 0; +} +table .span13 { + float: none; + width: 1004px; + margin-left: 0; +} +table .span14 { + float: none; + width: 1084px; + margin-left: 0; +} +table .span15 { + float: none; + width: 1164px; + margin-left: 0; +} +table .span16 { + float: none; + width: 1244px; + margin-left: 0; +} +table .span17 { + float: none; + width: 1324px; + margin-left: 0; +} +table .span18 { + float: none; + width: 1404px; + margin-left: 0; +} +table .span19 { + float: none; + width: 1484px; + margin-left: 0; +} +table .span20 { + float: none; + width: 1564px; + margin-left: 0; +} +table .span21 { + float: none; + width: 1644px; + margin-left: 0; +} +table .span22 { + float: none; + width: 1724px; + margin-left: 0; +} +table .span23 { + float: none; + width: 1804px; + margin-left: 0; +} +table .span24 { + float: none; + width: 1884px; + margin-left: 0; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} +[class^="icon-"]:last-child, +[class*=" icon-"]:last-child { + *margin-left: 0; +} +.icon-white { + background-image: url("../img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; +} +.icon-folder-open { + background-position: -408px -120px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.icon-hdd { + background-position: 0 -144px; +} +.icon-bullhorn { + background-position: -24px -144px; +} +.icon-bell { + background-position: -48px -144px; +} +.icon-certificate { + background-position: -72px -144px; +} +.icon-thumbs-up { + background-position: -96px -144px; +} +.icon-thumbs-down { + background-position: -120px -144px; +} +.icon-hand-right { + background-position: -144px -144px; +} +.icon-hand-left { + background-position: -168px -144px; +} +.icon-hand-up { + background-position: -192px -144px; +} +.icon-hand-down { + background-position: -216px -144px; +} +.icon-circle-arrow-right { + background-position: -240px -144px; +} +.icon-circle-arrow-left { + background-position: -264px -144px; +} +.icon-circle-arrow-up { + background-position: -288px -144px; +} +.icon-circle-arrow-down { + background-position: -312px -144px; +} +.icon-globe { + background-position: -336px -144px; +} +.icon-wrench { + background-position: -360px -144px; +} +.icon-tasks { + background-position: -384px -144px; +} +.icon-filter { + background-position: -408px -144px; +} +.icon-briefcase { + background-position: -432px -144px; +} +.icon-fullscreen { + background-position: -456px -144px; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; + opacity: 0.3; + filter: alpha(opacity=30); +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 4px 0; + margin: 1px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.dropdown-menu a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #333333; + white-space: nowrap; +} +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #369bd7; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: "\2191"; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -ms-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -ms-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.btn { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + *line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(top, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #e6e6e6; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #cccccc; + *border: 0; + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + /* Buttons in IE7 don't get borders, so darken on hover */ + + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} +.btn-small { + padding: 5px 9px; + font-size: 11px; + line-height: 16px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 2px 6px; + font-size: 11px; + line-height: 14px; +} +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} +.btn { + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +} +.btn-primary { + background-color: #368bd7; + background-image: -moz-linear-gradient(top, #369bd7, #3673d7); + background-image: -ms-linear-gradient(top, #369bd7, #3673d7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#369bd7), to(#3673d7)); + background-image: -webkit-linear-gradient(top, #369bd7, #3673d7); + background-image: -o-linear-gradient(top, #369bd7, #3673d7); + background-image: linear-gradient(top, #369bd7, #3673d7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#369bd7', endColorstr='#3673d7', GradientType=0); + border-color: #3673d7 #3673d7 #2050a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #3673d7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #3673d7; + *background-color: #2866cb; +} +.btn-primary:active, +.btn-primary.active { + background-color: #245bb6 \9; +} +.btn-warning { + background-color: #dd5600; + background-image: -moz-linear-gradient(top, #dd5600, #dd5600); + background-image: -ms-linear-gradient(top, #dd5600, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd5600), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #dd5600, #dd5600); + background-image: -o-linear-gradient(top, #dd5600, #dd5600); + background-image: linear-gradient(top, #dd5600, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd5600', endColorstr='#dd5600', GradientType=0); + border-color: #dd5600 #dd5600 #913800; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #dd5600; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #dd5600; + *background-color: #c44c00; +} +.btn-warning:active, +.btn-warning.active { + background-color: #aa4200 \9; +} +.btn-danger { + background-color: #c32627; + background-image: -moz-linear-gradient(top, #c71c22, #bd362f); + background-image: -ms-linear-gradient(top, #c71c22, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#c71c22), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #c71c22, #bd362f); + background-image: -o-linear-gradient(top, #c71c22, #bd362f); + background-image: linear-gradient(top, #c71c22, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c71c22', endColorstr='#bd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #bd362f; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #bd362f; + *background-color: #a9302a; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + background-color: #65a643; + background-image: -moz-linear-gradient(top, #73a839, #51a351); + background-image: -ms-linear-gradient(top, #73a839, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#73a839), to(#51a351)); + background-image: -webkit-linear-gradient(top, #73a839, #51a351); + background-image: -o-linear-gradient(top, #73a839, #51a351); + background-image: linear-gradient(top, #73a839, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#73a839', endColorstr='#51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #51a351; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #51a351; + *background-color: #499249; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + background-color: #6d76b3; + background-image: -moz-linear-gradient(top, #9760b3, #2f96b4); + background-image: -ms-linear-gradient(top, #9760b3, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#9760b3), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #9760b3, #2f96b4); + background-image: -o-linear-gradient(top, #9760b3, #2f96b4); + background-image: linear-gradient(top, #9760b3, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9760b3', endColorstr='#2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #2f96b4; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #2f96b4; + *background-color: #2a85a0; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + background-color: #a27a28; + background-image: -moz-linear-gradient(top, #f7b42c, #222222); + background-image: -ms-linear-gradient(top, #f7b42c, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f7b42c), to(#222222)); + background-image: -webkit-linear-gradient(top, #f7b42c, #222222); + background-image: -o-linear-gradient(top, #f7b42c, #222222); + background-image: linear-gradient(top, #f7b42c, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7b42c', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #222222; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #222222; + *background-color: #151515; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, +.btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-mini.dropdown-toggle { + padding-left: 5px; + padding-right: 5px; +} +.btn-group > .btn-small.dropdown-toggle { + *padding-top: 4px; + *padding-bottom: 4px; +} +.btn-group > .btn-large.dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #3673d7; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #dd5600; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-mini .caret { + margin-top: 5px; +} +.btn-small .caret { + margin-top: 6px; +} +.btn-large .caret { + margin-top: 6px; + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.dropup .btn-large .caret { + border-bottom: 5px solid #000000; + border-top: 0; +} +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #8bc5e8; + border: 1px solid #7ed0e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #1c628b; +} +.alert-heading { + color: inherit; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #ccddbb; + border-color: #c6d4aa; + color: #669533; +} +.alert-danger, +.alert-error { + background-color: #eddbe3; + border-color: #e8d1df; + color: #bd4247; +} +.alert-info { + background-color: #edebe1; + border-color: #e0d9cb; + color: #817b58; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.nav > .pull-right { + float: right; +} +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #369bd7; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover { + color: #ffffff; + background-color: #369bd7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: #369bd7; + border-bottom-color: #369bd7; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: #2071a1; + border-bottom-color: #2071a1; +} +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} +.nav > .dropdown.active > a:hover { + color: #000000; + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #dddddd #f5f5f5 #f5f5f5; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover { + border-color: #f5f5f5 #f5f5f5 #f5f5f5 #dddddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.navbar { + *position: relative; + *z-index: 2; + overflow: visible; + margin-bottom: 18px; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #50a8dc; + background-image: -moz-linear-gradient(top, #61b0df, #369bd7); + background-image: -ms-linear-gradient(top, #61b0df, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#61b0df), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #61b0df, #369bd7); + background-image: -o-linear-gradient(top, #61b0df, #369bd7); + background-image: linear-gradient(top, #61b0df, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#61b0df', endColorstr='#369bd7', GradientType=0); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + box-shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; +} +.navbar { + color: #f5f5f5; +} +.navbar .brand:hover { + text-decoration: none; +} +.navbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + line-height: 1; + color: #f5f5f5; +} +.navbar .navbar-text { + margin-bottom: 0; + line-height: 40px; +} +.navbar .navbar-link { + color: #f5f5f5; +} +.navbar .navbar-link:hover { + color: #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn { + margin: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; +} +.navbar-search .search-query { + padding: 4px 9px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #ffffff; + background-color: #a0d0ec; + border: 1px solid #288ecb; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.navbar-search .search-query:-moz-placeholder { + color: #ffffff; +} +.navbar-search .search-query:-ms-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query::-webkit-input-placeholder { + color: #ffffff; +} +.navbar-search .search-query:focus, +.navbar-search .search-query.focused { + padding: 5px 10px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; +} +.navbar .nav > li { + display: block; + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 9px 10px 11px; + line-height: 19px; + color: #f5f5f5; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + border-right: 1px solid #3887B3; + border-left: 1px solid #3887B3; +} +.navbar .btn { + display: inline-block; + padding: 4px 10px 4px; + margin: 5px 5px 6px; + line-height: 18px; +} +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} +.navbar .nav > li > a:hover { + background-color: transparent; + color: #ffffff; + text-decoration: none; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: rgba(0, 0, 0, 0.2); +} +.navbar .divider-vertical { + height: 40px; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: #369bd7; + border-right: 1px solid #61b0df; +} +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #50a8dc; + background-image: -moz-linear-gradient(top, #61b0df, #369bd7); + background-image: -ms-linear-gradient(top, #61b0df, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#61b0df), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #61b0df, #369bd7); + background-image: -o-linear-gradient(top, #61b0df, #369bd7); + background-image: linear-gradient(top, #61b0df, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#61b0df', endColorstr='#369bd7', GradientType=0); + border-color: #369bd7 #369bd7 #2071a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #369bd7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + background-color: #369bd7; + *background-color: #288ecb; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #2480b6 \9; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0, 0, 0, 0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .dropdown-menu:after { + border-top: 6px solid #ffffff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown .dropdown-toggle .caret, +.navbar .nav li.dropdown.open .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} +.navbar .nav li.dropdown.active .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: transparent; +} +.navbar .nav li.dropdown.active > .dropdown-toggle:hover { + color: #ffffff; +} +.navbar .pull-right .dropdown-menu, +.navbar .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right .dropdown-menu:before, +.navbar .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right .dropdown-menu:after, +.navbar .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + list-style: none; + background-color: #fbfbfb; + background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); + background-image: linear-gradient(top, #ffffff, #f5f5f5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} +.breadcrumb li { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb .divider { + padding: 0 5px; + color: #999999; +} +.breadcrumb .active a { + color: #333333; +} +.pagination { + height: 36px; + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination li { + display: inline; +} +.pagination a { + float: left; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: #999999; + cursor: default; +} +.pagination .disabled span, +.pagination .disabled a, +.pagination .disabled a:hover { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination li:last-child a { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pager { + margin-left: 0; + margin-bottom: 18px; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} +.pager .disabled a, +.pager .disabled a:hover { + color: #999999; + background-color: #fff; + cursor: default; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2060; +} +.modal-open .tooltip { + z-index: 2070; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -ms-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); +} +a.thumbnail:hover { + border-color: #369bd7; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} +.label, +.badge { + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; +} +.label { + padding: 1px 4px 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding: 1px 9px 2px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +a.label:hover, +a.badge:hover { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #bd4247; +} +.label-important[href], +.badge-important[href] { + background-color: #983538; +} +.label-warning, +.badge-warning { + background-color: #dd5600; +} +.label-warning[href], +.badge-warning[href] { + background-color: #aa4200; +} +.label-success, +.badge-success { + background-color: #669533; +} +.label-success[href], +.badge-success[href] { + background-color: #4c6f26; +} +.label-info, +.badge-info { + background-color: #817b58; +} +.label-info[href], +.badge-info[href] { + background-color: #625e43; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(top, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 18px; + color: #ffffff; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -ms-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(top, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -ms-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); +} +.progress-danger.progress-striped .bar { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); +} +.progress-success.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); +} +.progress-info.progress-striped .bar { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-warning .bar { + background-color: #f16e1a; + background-image: -moz-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -ms-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff7d2b), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #ff7d2b, #dd5600); + background-image: -o-linear-gradient(top, #ff7d2b, #dd5600); + background-image: linear-gradient(top, #ff7d2b, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff7d2b', endColorstr='#dd5600', GradientType=0); +} +.progress-warning.progress-striped .bar { + background-color: #ff7d2b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel .item > img { + display: block; + line-height: 1; +} +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} +.carousel .active { + left: 0; +} +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel .next { + left: 100%; +} +.carousel .prev { + left: -100%; +} +.carousel .next.left, +.carousel .prev.right { + left: 0; +} +.carousel .active.left { + left: -100%; +} +.carousel .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #f5f5f5; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit p { + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.navbar,.top-block { + font-family: 'Karla', sans-serif; +} +.navbar .navbar-inner { + background-color: #3f9fd9; +} +.navbar-inner{ + background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(0,0,0,0.15) 50%, rgba(30,30,30,0) 100%); +background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(50%,rgba(0,0,0,0.15)), color-stop(100%,rgba(30,30,30,0))); +background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: -o-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(0,0,0,0.15) 50%,rgba(30,30,30,0) 100%); +filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#001e1e1e',GradientType=0 ); +} +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.active.open > .dropdown-toggle { + background-color: rgba(0, 0, 0, 0.2); +} +.navbar .search-query { + border: 1px solid #2480b6; +} +.navbar .nav-collapse.in > .nav > li .dropdown-menu a { + color: #ffffff; +} +.navbar .nav-collapse.in > .nav > li .dropdown-menu a:hover { + color: #ffffff; +} +.navbar .nav-collapse.in .nav li > a { + color: #ffffff; +} +.navbar .nav-collapse.in .nav li > a:hover { + background-color: #2B7CAC; +} +.navbar .btn-navbar:hover { + background-color: #cccccc; +} +div.subnav { + font-family: 'Karla', sans-serif; +} +.btn { + background-color: #ffffff; + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(5%, #ffffff), to(#ffffff)); + background-image: -webkit-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: -moz-linear-gradient(top, #ffffff, #ffffff 5%, #ffffff); + background-image: -ms-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: -o-linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-image: linear-gradient(#ffffff, #ffffff 5%, #ffffff); + background-repeat: no-repeat; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ffffff', GradientType=0); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn:hover { + background-position: 0 0; +} +.btn-primary { + background-color: #43a1da; + background-image: -moz-linear-gradient(top, #4ba6db, #369bd7); + background-image: -ms-linear-gradient(top, #4ba6db, #369bd7); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#4ba6db), to(#369bd7)); + background-image: -webkit-linear-gradient(top, #4ba6db, #369bd7); + background-image: -o-linear-gradient(top, #4ba6db, #369bd7); + background-image: linear-gradient(top, #4ba6db, #369bd7); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4ba6db', endColorstr='#369bd7', GradientType=0); + border-color: #369bd7 #369bd7 #2071a1; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #369bd7; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #369bd7; + *background-color: #288ecb; +} +.btn-primary:active, +.btn-primary.active { + background-color: #2480b6 \9; +} +.btn-info { + background-color: #9e6ab8; + background-image: -moz-linear-gradient(top, #a271bb, #9760b3); + background-image: -ms-linear-gradient(top, #a271bb, #9760b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#a271bb), to(#9760b3)); + background-image: -webkit-linear-gradient(top, #a271bb, #9760b3); + background-image: -o-linear-gradient(top, #a271bb, #9760b3); + background-image: linear-gradient(top, #a271bb, #9760b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#a271bb', endColorstr='#9760b3', GradientType=0); + border-color: #9760b3 #9760b3 #6f4086; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #9760b3; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #9760b3; + *background-color: #8b51a9; +} +.btn-info:active, +.btn-info.active { + background-color: #7d4898 \9; +} +.btn-success { + background-color: #7bb33d; + background-image: -moz-linear-gradient(top, #80bb3f, #73a839); + background-image: -ms-linear-gradient(top, #80bb3f, #73a839); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#80bb3f), to(#73a839)); + background-image: -webkit-linear-gradient(top, #80bb3f, #73a839); + background-image: -o-linear-gradient(top, #80bb3f, #73a839); + background-image: linear-gradient(top, #80bb3f, #73a839); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80bb3f', endColorstr='#73a839', GradientType=0); + border-color: #73a839 #73a839 #4c6f26; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #73a839; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #73a839; + *background-color: #669533; +} +.btn-success:active, +.btn-success.active { + background-color: #59822c \9; +} +.btn-warning { + background-color: #ec5c00; + background-image: -moz-linear-gradient(top, #f76000, #dd5600); + background-image: -ms-linear-gradient(top, #f76000, #dd5600); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f76000), to(#dd5600)); + background-image: -webkit-linear-gradient(top, #f76000, #dd5600); + background-image: -o-linear-gradient(top, #f76000, #dd5600); + background-image: linear-gradient(top, #f76000, #dd5600); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f76000', endColorstr='#dd5600', GradientType=0); + border-color: #dd5600 #dd5600 #913800; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #dd5600; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #dd5600; + *background-color: #c44c00; +} +.btn-warning:active, +.btn-warning.active { + background-color: #aa4200 \9; +} +.btn-danger { + background-color: #d41e24; + background-image: -moz-linear-gradient(top, #dd1f26, #c71c22); + background-image: -ms-linear-gradient(top, #dd1f26, #c71c22); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#dd1f26), to(#c71c22)); + background-image: -webkit-linear-gradient(top, #dd1f26, #c71c22); + background-image: -o-linear-gradient(top, #dd1f26, #c71c22); + background-image: linear-gradient(top, #dd1f26, #c71c22); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dd1f26', endColorstr='#c71c22', GradientType=0); + border-color: #c71c22 #c71c22 #841317; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #c71c22; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #c71c22; + *background-color: #b1191e; +} +.btn-danger:active, +.btn-danger.active { + background-color: #9a161a \9; +} +.btn-inverse { + background-color: #f8b93b; + background-image: -moz-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -ms-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f8bd45), to(#f7b42c)); + background-image: -webkit-linear-gradient(top, #f8bd45, #f7b42c); + background-image: -o-linear-gradient(top, #f8bd45, #f7b42c); + background-image: linear-gradient(top, #f8bd45, #f7b42c); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f8bd45', endColorstr='#f7b42c', GradientType=0); + border-color: #f7b42c #f7b42c #cf8d08; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + *background-color: #f7b42c; + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #f7b42c; + *background-color: #f6ab13; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #e79e09 \9; +} +i[class^="icon-"] { + opacity: 0.8; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} diff --git a/Bench4Q-Web/src/main/webapp/lib/chrisma/css/charisma-app.css b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/charisma-app.css new file mode 100644 index 00000000..cb48f731 --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/charisma-app.css @@ -0,0 +1,501 @@ +@import url(http://fonts.googleapis.com/css?family=Shojumaru); + +select{ +background-color:#fff; +} + +.top-block{ +font-size:14px; +text-align: center; +padding: 5px; +margin-bottom:10px; +font-weight:bold; +position: relative; +display: block; +line-height: 22px; +text-shadow: 0 0 1px #DDD; +text-decoration:none; +-webkit-box-shadow: inset 0 0 0 1px #FAFAFA; +-moz-box-shadow: inset 0 0 0 1px #FAFAFA; +box-shadow: inset 0 0 0 1px #FAFAFA; +background: -moz-linear-gradient(top, rgba(30,87,153,0.2) 0%, rgba(125,185,232,0) 100%); +background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,0.2)), color-stop(100%,rgba(125,185,232,0))); +background: -webkit-linear-gradient(top, rgba(30,87,153,0.2) 0%,rgba(125,185,232,0) 100%); +background: -o-linear-gradient(top, rgba(30,87,153,0.2) 0%,rgba(125,185,232,0) 100%); +background: -ms-linear-gradient(top, rgba(30,87,153,0.2) 0%,rgba(125,185,232,0) 100%); +background: linear-gradient(to bottom, rgba(30,87,153,0.2) 0%,rgba(125,185,232,0) 100%); +filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#331e5799', endColorstr='#007db9e8',GradientType=0 ); +} + +.top-block span{ +clear:both; +} + + +.top-block:hover{ +text-decoration:none; +} + +.notification { +display: block; +position: absolute; +top: -10px; +right: -5px; +line-height: 16px; +height: 16px; +padding: 0 5px; +font-family: Arial, sans-serif; +color: white !important; +text-shadow: 0 1px +hsla(0, 0%, 0%, 0.25); +border-width: 1px; +border-style: solid; +border-radius: 10px; +-webkit-border-radius: 10px; +-moz-border-radius: 10px; +-webkit-box-shadow: 0 1px 1px +hsla(0, 0%, 0%, 0.08), inset 0 1px +hsla(0, 100%, 100%, 0.3); +-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.08), inset 0 1px rgba(255, 255, 255, 0.3); +box-shadow: 0 1px 1px +hsla(0, 0%, 0%, 0.08), inset 0 1px +hsla(0, 100%, 100%, 0.3); +} + +.notification { +border-color: #2FABE9; +background-color: #67C2EF; +background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, hsl(200, 80%, 82%)), color-stop(100%, hsl(200, 81%, 67%))); +background-image: -webkit-linear-gradient(top, hsl(200, 80%, 82%), hsl(200, 81%, 67%)); +background-image: -moz-linear-gradient(top, hsl(200, 80%, 82%), hsl(200, 81%, 67%)); +background-image: -ms-linear-gradient(top, hsl(200, 80%, 82%), hsl(200, 81%, 67%)); +background-image: -o-linear-gradient(top, hsl(200, 80%, 82%), hsl(200, 81%, 67%)); +background-image: linear-gradient(top, hsl(200, 80%, 82%), hsl(200, 81%, 67%)); +} + +.notification.green { +border-color: #5AAD34; +background-color: #78CD51; +background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, hsl(101, 54%, 71%)), color-stop(100%, hsl(101, 55%, 56%))); +background-image: -webkit-linear-gradient(top, hsl(101, 54%, 71%), hsl(101, 55%, 56%)); +background-image: -moz-linear-gradient(top, hsl(101, 54%, 71%), hsl(101, 55%, 56%)); +background-image: -ms-linear-gradient(top, hsl(101, 54%, 71%), hsl(101, 55%, 56%)); +background-image: -o-linear-gradient(top, hsl(101, 54%, 71%), hsl(101, 55%, 56%)); +background-image: linear-gradient(top, hsl(101, 54%, 71%), hsl(101, 55%, 56%)); +} + +.notification.yellow { +border-color: #F4A506; +background-color: #FABB3D; +background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, hsl(40, 95%, 76%)), color-stop(100%, hsl(40, 95%, 61%))); +background-image: -webkit-linear-gradient(top, hsl(40, 95%, 76%), hsl(40, 95%, 61%)); +background-image: -moz-linear-gradient(top, hsl(40, 95%, 76%), hsl(40, 95%, 61%)); +background-image: -ms-linear-gradient(top, hsl(40, 95%, 76%), hsl(40, 95%, 61%)); +background-image: -o-linear-gradient(top, hsl(40, 95%, 76%), hsl(40, 95%, 61%)); +background-image: linear-gradient(top, hsl(40, 95%, 76%), hsl(40, 95%, 61%)); +} + +.notification.red { +border-color: #FA5833; +background-color: #FA603D; +background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, hsl(11, 95%, 76%)), color-stop(100%, hsl(11, 95%, 61%))); +background-image: -webkit-linear-gradient(top, hsl(11, 95%, 76%), hsl(11, 95%, 61%)); +background-image: -moz-linear-gradient(top, hsl(11, 95%, 76%), hsl(11, 95%, 61%)); +background-image: -ms-linear-gradient(top, hsl(11, 95%, 76%), hsl(11, 95%, 61%)); +background-image: -o-linear-gradient(top, hsl(11, 95%, 76%), hsl(11, 95%, 61%)); +background-image: linear-gradient(top, hsl(11, 95%, 76%), hsl(11, 95%, 61%)); +} + +#external-events { +float: left; +width: 15%; +padding: 10px; +text-align: left; +} +.external-event{ +margin: 5px; +cursor:move; +} +#calendar { +float: right; +width: 80%; +} + + + +.box{ +border: 1px solid #DEDEDE; +border-radius:3px; +-webkit-border-radius:3px; +-moz-border-radius:3px; +margin-top: 10px; +margin-bottom: 10px ; +box-shadow: 0 0 10px rgba(189, 189, 189, 0.4); +-webkit-box-shadow: 0 0 10px rgba(189, 189, 189, 0.4); +-moz-box-shadow: 0 0 10px rgba(189, 189, 189, 0.4); +} + +.box-header{ +border:none; +padding-top:5px; +border-bottom: 1px solid #DEDEDE; +border-radius:3px 3px 0 0; +-webkit-border-radius:3px 3px 0 0; +-moz-border-radius:3px 3px 0 0; +height:12px; +min-height:12px; +margin-bottom: 0; +cursor:move; +font-weight:bold; +font-size:16px; +background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(0,0,0,0.1) 100%); +background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(0,0,0,0.1))); +background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.1) 100%); +background: -o-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.1) 100%); +background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.1) 100%); +background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(0,0,0,0.1) 100%); +filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#1a000000',GradientType=0 ); + +} + +.box-header h2{ +font-size:15px; +width:auto; +clear:none; +float:left; +line-height:25px; +} +.box-header h3{ +font-size:13px; +width:auto; +clear:none; +float:left; +line-height:25px; +} +.box-header h2 > i{ +margin-top:1px; +} +.box-icon{ +float:right; +} +.box-icon a{ +clear:none; +float:left; +margin:0 2px; +height: 18px; +width:5px; +margin-top: -1px; +} +.box-icon a i{ +margin-left:-4.5px; +} +.box-content{ +padding:10px; +} + + +.btn-round{ +border-radius: 40px; +-webkit-border-radius: 40px; +-moz-border-radius: 40px; +font-size:12px; +padding-top:4px; +} + +ul.dashboard-list li{ +padding: 7px 0; +list-style:none; +border-bottom: 1px solid #EBEBEB; +border-top: 1px solid white; +} + +ul.dashboard-list a:hover{ +text-decoration:none; +} + +ul.dashboard-list{ +margin:0; +} + +ul.dashboard-list li a span { +display: inline-block; +font-size: 18px; +font-weight: bold; +margin-right: 10px; +text-align: right; +width: 70px; +zoom: 1; +} + +.dashboard-avatar{ +height: 50px; +width: 50px; +padding: 1px; +float: left; +margin-left: 15px; +margin-right: 15px; +border: 1px solid #EBEBEB; +} + +#prependedInput,#appendedPrependedInput,#appendedInputButtons,#appendedInputButton{ +width:200px; +} +#appendedInput{ +width:75px; +} +.thumbnail{ +background-color:white; +z-index:2; +position:relative; +margin-bottom:40px !important; +} +.thumbnails > li{ +margin-left:15px; +} +.thumbnail img,.thumbnail > a{ +z-index:2; +height:100px; +width:100px; +position:relative; +display: block; +} + +img.grayscale{ +-webkit-filter: grayscale(1); +-webkit-filter: grayscale(100%); +-moz-filter: grayscale(100%); +-ms-filter: grayscale(100%); +-o-filter: grayscale(100%); +/*filter: url(desaturate.svg#grayscale); +filter: gray; +filter: grayscale(100%); */ +} + +.thumbnail .gallery-controls{ +position:absolute; +z-index:1; +margin-top:-30px; +height:22px; +min-height:22px; +width:80px; +padding:9px; +} +.thumbnail .gallery-controls p{ +display:block; +margin:auto; +width:100%; +} +label div.checker,label div.radio{ +margin-bottom:3px; +} +div.uploader{ +border-radius:14px; +-webkit-border-radius:14px; +-moz-border-radius:14px; +} +footer{ +clear:both; +} +footer .pull-right{ +float:right; +margin-right:10px; +} +footer .pull-left{ +float:left; +margin-left:10px; +} +.docs-input-sizes select, .docs-input-sizes input[type="text"] { +display: block; +margin-bottom: 9px; +} + +div.center,p.center,img.center{ +margin-left: auto !important; +margin-right: auto !important; +float:none !important; +display: block; +text-align:center; +} + +.stackControls{ +padding:5px; +} + +.clear{ +clear:both; +width:0px; +height:0px; +} + +.sidebar-nav{ +min-height:0; +box-shadow: 0 0 10px #BDBDBD; +-webkit-box-shadow: 0 0 10px #BDBDBD; +-moz-box-shadow: 0 0 10px #BDBDBD; +border-radius: 5px; +-webkit-border-radius: 5px; +-moz-border-radius: 5px; +margin-bottom: 0; +padding-bottom:0; +} +.sidebar-nav > ul > li:not(.nav-header){ +margin-right:-2px; +margin-left:-2px; +} +.brand{ +font-family: 'Shojumaru', cursive, Arial, serif; +letter-spacing:2px; +text-shadow:1px 1px 5px rgba(0, 0, 0, 0.5); +width:166px; +} +.brand img{ +float:left; +height:20px; +width:20px; +margin-right:5px; +} +.brand span{ +float:left; +} +@media (max-width: 979px){ +.sidebar-nav{ +padding:0; +margin-bottom:0; +} +.theme-text{ + display:none; +} +} +@media (min-width: 768px) and (max-width: 979px) { +.box-icon{ + display:none; +} +.box-header h2{ + font-size:13px !important; +} +.box-header h3{ + font-size:11px !important; +} +.main-menu-span{ + width:6.2% !important; + margin-right:4%; +} +} + +.navbar-search{ +margin-left:10px; +} +.navbar-inner{ +border-radius:0 0 10px 10px; +-webkit-border-radius:0 0 10px 10px; +-moz-border-radius:0 0 10px 10px; +padding-top:5px; +padding-bottom:5px; +} +div.dataTables_length select { +width: 50px; +} +.dataTables_filter input, .dataTables_length select { +display: inline-block; +margin-bottom: 0; +} +ul.ajax-loaders li{ +display:inline-block; +list-style:none; +padding:10px; +} +ul.ajax-loaders{ +min-height:80px; +} +.bs-icons li{ +list-style:none; +} +#for-is-ajax{ +padding-left: 12px; +cursor:pointer; +} +#loading{ +margin-top: 20px; +width:128px; +font-weight: bold; +} +#loading div.center{ +margin-top:10px; +height:15px; +width:128px; +background:url(../img/ajax-loaders/ajax-loader-6.gif); +} + +.box-content .nav-tabs{ +margin-right:-10px; +margin-left:-10px; +} +#inputIcon{ +width:200px; +} +.show-grid [class*="span"] { +background-color: #EDEDED; +text-align: center; +-webkit-border-radius: 3px; +-moz-border-radius: 3px; +border-radius: 3px; +min-height: 30px; +line-height: 30px; +} +.show-grid { +margin-top: 10px; +margin-bottom: 20px; +color:black; +} +.show-grid:hover [class*="span"] { +background: #DEDEDE; +} +.login-header{ +padding-top:30px; +height:120px; +} +.pull-left{ +float:left !important; +} +.pull-right{ +float:right !important; +} +.remember{ +margin-top:3px; +} +.green { +color: #458746; +} +.red { +color: #B94846; +} +.blue { +color: #3986AC; +} +.yellow { +color: #F99406; +} +.login-box{ + +} +.login-box .input-prepend{ +margin-bottom: 10px; +} +.login-box .btn{ +margin-top:15px; +width:100% +} +.charisma_qr{ +height:136px; +width:136px; +border:solid grey 1px; +border-radius:2px; +-webkit-border-radius:2px; +-moz-border-radius:2px; +box-shadow: 0 0 10px #BDBDBD; +-webkit-box-shadow: 0 0 10px #BDBDBD; +-moz-box-shadow: 0 0 10px #BDBDBD; +} +.box-content.buttons{ +min-height:297px; +} diff --git a/Bench4Q-Web/src/main/webapp/lib/chrisma/css/opa-icons.css b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/opa-icons.css new file mode 100644 index 00000000..1b28938b --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/chrisma/css/opa-icons.css @@ -0,0 +1,366 @@ +.active .icon.icon-add,.icon.icon-add,.icon.icon-add:hover {background-position : -16px -128px ;} +.active .icon.icon-alert,.icon.icon-alert,.icon.icon-alert:hover {background-position : -64px -128px ;} +.active .icon.icon-archive,.icon.icon-archive,.icon.icon-archive:hover {background-position : -32px -144px ;} +.active .icon.icon-arrow-4diag,.icon.icon-arrow-4diag,.icon.icon-arrow-4diag:hover {background-position : -208px -32px ;} +.active .icon.icon-arrow-e,.icon.icon-arrow-e,.icon.icon-arrow-e:hover {background-position : -32px -32px ;} +.active .icon.icon-arrow-e-w,.icon.icon-arrow-e-w,.icon.icon-arrow-e-w:hover {background-position : -160px -32px ;} +.active .icon.icon-arrow-n,.icon.icon-arrow-n,.icon.icon-arrow-n:hover {background-position : 0 -32px ;} +.active .icon.icon-arrow-n-s,.icon.icon-arrow-n-s,.icon.icon-arrow-n-s:hover {background-position : -128px -32px ;} +.active .icon.icon-arrow-ne,.icon.icon-arrow-ne,.icon.icon-arrow-ne:hover {background-position : -16px -32px ;} +.active .icon.icon-arrow-ne-sw,.icon.icon-arrow-ne-sw,.icon.icon-arrow-ne-sw:hover {background-position : -144px -32px ;} +.active .icon.icon-arrow-nesw,.icon.icon-arrow-nesw,.icon.icon-arrow-nesw:hover {background-position : -192px -32px ;} +.active .icon.icon-arrow-nw,.icon.icon-arrow-nw,.icon.icon-arrow-nw:hover {background-position : -112px -32px ;} +.active .icon.icon-arrow-s,.icon.icon-arrow-s,.icon.icon-arrow-s:hover {background-position : -64px -32px ;} +.active .icon.icon-arrow-se,.icon.icon-arrow-se,.icon.icon-arrow-se:hover {background-position : -48px -32px ;} +.active .icon.icon-arrow-se-nw,.icon.icon-arrow-se-nw,.icon.icon-arrow-se-nw:hover {background-position : -176px -32px ;} +.active .icon.icon-arrow-sw,.icon.icon-arrow-sw,.icon.icon-arrow-sw:hover {background-position : -80px -32px ;} +.active .icon.icon-arrow-w,.icon.icon-arrow-w,.icon.icon-arrow-w:hover {background-position : -96px -32px ;} +.active .icon.icon-arrowrefresh-e,.icon.icon-arrowrefresh-e,.icon.icon-arrowrefresh-e:hover {background-position : -160px -64px ;} +.active .icon.icon-arrowrefresh-n,.icon.icon-arrowrefresh-n,.icon.icon-arrowrefresh-n:hover {background-position : -144px -64px ;} +.active .icon.icon-arrowrefresh-s,.icon.icon-arrowrefresh-s,.icon.icon-arrowrefresh-s:hover {background-position : -176px -64px ;} +.active .icon.icon-arrowrefresh-w,.icon.icon-arrowrefresh-w,.icon.icon-arrowrefresh-w:hover {background-position : -128px -64px ;} +.active .icon.icon-arrowreturn-en,.icon.icon-arrowreturn-en,.icon.icon-arrowreturn-en:hover {background-position : -112px -64px ;} +.active .icon.icon-arrowreturn-es,.icon.icon-arrowreturn-es,.icon.icon-arrowreturn-es:hover {background-position : -80px -64px ;} +.active .icon.icon-arrowreturn-ne,.icon.icon-arrowreturn-ne,.icon.icon-arrowreturn-ne:hover {background-position : -32px -64px ;} +.active .icon.icon-arrowreturn-nw,.icon.icon-arrowreturn-nw,.icon.icon-arrowreturn-nw:hover {background-position : -48px -64px ;} +.active .icon.icon-arrowreturn-se,.icon.icon-arrowreturn-se,.icon.icon-arrowreturn-se:hover {background-position : 0 -64px ;} +.active .icon.icon-arrowreturn-sw,.icon.icon-arrowreturn-sw,.icon.icon-arrowreturn-sw:hover {background-position : -16px -64px ;} +.active .icon.icon-arrowreturn-wn,.icon.icon-arrowreturn-wn,.icon.icon-arrowreturn-wn:hover {background-position : -96px -64px ;} +.active .icon.icon-arrowreturn-ws,.icon.icon-arrowreturn-ws,.icon.icon-arrowreturn-ws:hover {background-position : -64px -64px ;} +.active .icon.icon-arrowstop-e,.icon.icon-arrowstop-e,.icon.icon-arrowstop-e:hover {background-position : -176px 0 ;} +.active .icon.icon-arrowstop-n,.icon.icon-arrowstop-n,.icon.icon-arrowstop-n:hover {background-position : -160px 0 ;} +.active .icon.icon-arrowstop-s,.icon.icon-arrowstop-s,.icon.icon-arrowstop-s:hover {background-position : -192px 0 ;} +.active .icon.icon-arrowstop-w,.icon.icon-arrowstop-w,.icon.icon-arrowstop-w:hover {background-position : -208px 0 ;} +.active .icon.icon-arrowthick-e,.icon.icon-arrowthick-e,.icon.icon-arrowthick-e:hover {background-position : -32px -48px ;} +.active .icon.icon-arrowthick-n,.icon.icon-arrowthick-n,.icon.icon-arrowthick-n:hover {background-position : 0 -48px ;} +.active .icon.icon-arrowthick-ne,.icon.icon-arrowthick-ne,.icon.icon-arrowthick-ne:hover {background-position : -16px -48px ;} +.active .icon.icon-arrowthick-nw,.icon.icon-arrowthick-nw,.icon.icon-arrowthick-nw:hover {background-position : -112px -48px ;} +.active .icon.icon-arrowthick-s,.icon.icon-arrowthick-s,.icon.icon-arrowthick-s:hover {background-position : -64px -48px ;} +.active .icon.icon-arrowthick-se,.icon.icon-arrowthick-se,.icon.icon-arrowthick-se:hover {background-position : -48px -48px ;} +.active .icon.icon-arrowthick-sw,.icon.icon-arrowthick-sw,.icon.icon-arrowthick-sw:hover {background-position : -80px -48px ;} +.active .icon.icon-arrowthick-w,.icon.icon-arrowthick-w,.icon.icon-arrowthick-w:hover {background-position : -96px -48px ;} +.active .icon.icon-attachment,.icon.icon-attachment,.icon.icon-attachment:hover {background-position : -80px -144px ;} +.active .icon.icon-audio,.icon.icon-audio,.icon.icon-audio:hover {background-position : -208px -128px ;} +.active .icon.icon-basket,.icon.icon-basket,.icon.icon-basket:hover {background-position : -144px -128px ;} +.active .icon.icon-book,.icon.icon-book,.icon.icon-book:hover {background-position : -64px -80px ;} +.active .icon.icon-book-empty,.icon.icon-book-empty,.icon.icon-book-empty:hover {background-position : -80px -80px ;} +.active .icon.icon-bookmark,.icon.icon-bookmark,.icon.icon-bookmark:hover {background-position : -144px -80px ;} +.active .icon.icon-briefcase,.icon.icon-briefcase,.icon.icon-briefcase:hover {background-position : -240px -112px ;} +.active .icon.icon-bullet-off,.icon.icon-bullet-off,.icon.icon-bullet-off:hover {background-position : -208px -48px ;} +.active .icon.icon-bullet-on,.icon.icon-bullet-on,.icon.icon-bullet-on:hover {background-position : -192px -48px ;} +.active .icon.icon-calendar,.icon.icon-calendar,.icon.icon-calendar:hover {background-position : -16px -112px ;} +.active .icon.icon-cancel,.icon.icon-cancel,.icon.icon-cancel:hover {background-position : -176px -80px ;} +.active .icon.icon-carat-1-e,.icon.icon-carat-1-e,.icon.icon-carat-1-e:hover {background-position : -32px -16px ;} +.active .icon.icon-carat-1-n,.icon.icon-carat-1-n,.icon.icon-carat-1-n:hover {background-position : 0 -16px ;} +.active .icon.icon-carat-1-ne,.icon.icon-carat-1-ne,.icon.icon-carat-1-ne:hover {background-position : -16px -16px ;} +.active .icon.icon-carat-1-nw,.icon.icon-carat-1-nw,.icon.icon-carat-1-nw:hover {background-position : -112px -16px ;} +.active .icon.icon-carat-1-s,.icon.icon-carat-1-s,.icon.icon-carat-1-s:hover {background-position : -64px -16px ;} +.active .icon.icon-carat-1-se,.icon.icon-carat-1-se,.icon.icon-carat-1-se:hover {background-position : -48px -16px ;} +.active .icon.icon-carat-1-sw,.icon.icon-carat-1-sw,.icon.icon-carat-1-sw:hover {background-position : -80px -16px ;} +.active .icon.icon-carat-1-w,.icon.icon-carat-1-w,.icon.icon-carat-1-w:hover {background-position : -96px -16px ;} +.active .icon.icon-carat-2-ew,.icon.icon-carat-2-ew,.icon.icon-carat-2-ew :hover {background-position : -144px -16px ;} +.active .icon.icon-carat-2-ns,.icon.icon-carat-2-ns,.icon.icon-carat-2-ns:hover {background-position : -128px -16px ;} +.active .icon.icon-cart,.icon.icon-cart,.icon.icon-cart:hover {background-position : -128px -128px ;} +.active .icon.icon-check,.icon.icon-check,.icon.icon-check:hover {background-position : -208px -16px ;} +.active .icon.icon-clipboard,.icon.icon-clipboard,.icon.icon-clipboard:hover {background-position : -80px -96px ;} +.active .icon.icon-clock,.icon.icon-clock,.icon.icon-clock:hover {background-position : -32px -112px ;} +.active .icon.icon-close,.icon.icon-close,.icon.icon-close:hover {background-position : -192px -16px ;} +.active .icon.icon-comment,.icon.icon-comment,.icon.icon-comment:hover {background-position : -112px -128px ;} +.active .icon.icon-comment-text,.icon.icon-comment-text,.icon.icon-comment-text:hover {background-position : -80px -128px ;} +.active .icon.icon-comment-video,.icon.icon-comment-video,.icon.icon-comment-video:hover {background-position : -96px -128px ;} +.active .icon.icon-compose,.icon.icon-compose,.icon.icon-compose:hover {background-position : 0 -144px ;} +.active .icon.icon-contacts,.icon.icon-contacts,.icon.icon-contacts:hover {background-position : -176px -112px ;} +.active .icon.icon-copy,.icon.icon-copy,.icon.icon-copy:hover {background-position : -144px -96px ;} +.active .icon.icon-cross,.icon.icon-cross,.icon.icon-cross:hover {background-position : 0 -128px ;} +.active .icon.icon-date,.icon.icon-date,.icon.icon-cdate:hover {background-position : 0 -112px ;} +.active .icon.icon-doc,.icon.icon-doc,.icon.icon-doc:hover {background-position : -192px -96px ;} +.active .icon.icon-document,.icon.icon-document,.icon.icon-document:hover {background-position : -224px -96px ;} +.active .icon.icon-edit,.icon.icon-edit,.icon.icon-edit:hover {background-position : -112px -96px ;} +.active .icon.icon-envelope-closed,.icon.icon-envelope-closed,.icon.icon-envelope-closed:hover {background-position : -48px -112px ;} +.active .icon.icon-envelope-open,.icon.icon-envelope-open,.icon.icon-envelope-open:hover {background-position : -64px -112px ;} +.active .icon.icon-extlink,.icon.icon-extlink,.icon.icon-extlink:hover {background-position : -240px -32px ;} +.active .icon.icon-flag,.icon.icon-flag,.icon.icon-flag:hover {background-position : -128px -80px ;} +.active .icon.icon-folder-collapsed,.icon.icon-folder-collapsed,.icon.icon-folder-collapsed:hover {background-position : -96px -80px ;} +.active .icon.icon-folder-open,.icon.icon-folder-open,.icon.icon-folder-open:hover {background-position : -112px -80px ;} +.active .icon.icon-gear,.icon.icon-gear,.icon.icon-gear:hover {background-position : 0 -96px ;} +.active .icon.icon-globe,.icon.icon-globe,.icon.icon-globe:hover {background-position : -160px -112px ;} +.active .icon.icon-heart,.icon.icon-heart,.icon.icon-heart:hover {background-position : -160px -80px ;} +.active .icon.icon-help,.icon.icon-help,.icon.icon-help:hover {background-position : -224px -16px ;} +.active .icon.icon-home,.icon.icon-home,.icon.icon-home:hover {background-position : 0 -80px ;} +.active .icon.icon-image,.icon.icon-image,.icon.icon-image:hover {background-position : -208px -112px ;} +.active .icon.icon-inbox,.icon.icon-inbox,.icon.icon-inbox:hover {background-position : -16px -144px ;} +.active .icon.icon-info,.icon.icon-info,.icon.icon-info:hover {background-position : -48px -128px ;} +.active .icon.icon-key,.icon.icon-key,.icon.icon-key:hover {background-position : -64px -96px ;} +.active .icon.icon-lightbulb,.icon.icon-lightbulb,.icon.icon-lightbulb:hover {background-position : -240px -80px ;} +.active .icon.icon-link,.icon.icon-link,.icon.icon-link:hover {background-position : -112px -112px ;} +.active .icon.icon-locked,.icon.icon-locked,.icon.icon-locked:hover {background-position : -32px -96px ;} +.active .icon.icon-mail-closed,.icon.icon-mail-closed,.icon.icon-mail-closed:hover {background-position : -80px -112px ;} +.active .icon.icon-mail-open,.icon.icon-mail-open,.icon.icon-mail-open:hover {background-position : -96px -112px ;} +.active .icon.icon-messages,.icon.icon-messages,.icon.icon-messages:hover {background-position : -160px -128px ;} +.active .icon.icon-minus,.icon.icon-minus,.icon.icon-minus:hover {background-position : -176px -16px ;} +.active .icon.icon-newwin,.icon.icon-newwin,.icon.icon-newwin:hover {background-position : -224px -32px ;} +.active .icon.icon-note,.icon.icon-note,.icon.icon-note:hover {background-position : -160px -96px ;} +.active .icon.icon-notice,.icon.icon-notice,.icon.icon-notice:hover {background-position : -240px -16px ;} +.active .icon.icon-page,.icon.icon-page,.icon.icon-page:hover {background-position : -128px -96px ;} +.active .icon.icon-pdf,.icon.icon-pdf,.icon.icon-pdf:hover {background-position : -176px -96px ;} +.active .icon.icon-pin,.icon.icon-pin,.icon.icon-pin:hover {background-position : -208px -80px ;} +.active .icon.icon-plus,.icon.icon-plus,.icon.icon-plus:hover {background-position : -160px -16px ;} +.active .icon.icon-print,.icon.icon-print,.icon.icon-print:hover {background-position : -32px -80px ;} +.active .icon.icon-profile,.icon.icon-profile,.icon.icon-profile:hover {background-position : -192px -112px ;} +.active .icon.icon-redo,.icon.icon-redo,.icon.icon-redo:hover {background-position : -144px -48px ;} +.active .icon.icon-refresh,.icon.icon-refresh,.icon.icon-refresh:hover {background-position : -176px -48px ;} +.active .icon.icon-remove,.icon.icon-remove,.icon.icon-remove:hover {background-position : -32px -128px ;} +.active .icon.icon-reply,.icon.icon-reply,.icon.icon-reply:hover {background-position : -48px -144px ;} +.active .icon.icon-replyall,.icon.icon-replyall,.icon.icon-replyall:hover {background-position : -160px -48px ;} +.active .icon.icon-rssfeed,.icon.icon-rssfeed,.icon.icon-rssfeed:hover {background-position : -240px -64px ;} +.active .icon.icon-save,.icon.icon-save,.icon.icon-save:hover {background-position : -48px -80px ;} +.active .icon.icon-scissors,.icon.icon-scissors,.icon.icon-scissors:hover {background-position : -96px -96px ;} +.active .icon.icon-script,.icon.icon-script,.icon.icon-script:hover {background-position : -240px -96px ;} +.active .icon.icon-search,.icon.icon-search,.icon.icon-search:hover {background-position : -192px -64px ;} +.active .icon.icon-sent,.icon.icon-sent,.icon.icon-sent:hover {background-position : -64px -144px ;} +.active .icon.icon-shuffle,.icon.icon-shuffle,.icon.icon-shuffle:hover {background-position : -240px 0 ;} +.active .icon.icon-square-minus,.icon.icon-square-minus,.icon.icon-square-minus:hover {background-position : -176px -240px ;} +.active .icon.icon-square-plus,.icon.icon-square-plus,.icon.icon-square-plus:hover {background-position : -160px -240px ;} +.active .icon.icon-star-off,.icon.icon-star-off,.icon.icon-star-off:hover {background-position : -240px -48px ;} +.active .icon.icon-star-on,.icon.icon-star-on,.icon.icon-star-on:hover {background-position : -224px -48px ;} +.active .icon.icon-suitcase,.icon.icon-suitcase,.icon.icon-suitcase:hover {background-position : -224px -112px ;} +.active .icon.icon-tag,.icon.icon-tag,.icon.icon-tag:hover {background-position : -224px -80px ;} +.active .icon.icon-transfer-ew,.icon.icon-transfer-ew,.icon.icon-transfer-ew:hover {background-position : -224px 0 ;} +.active .icon.icon-trash,.icon.icon-trash,.icon.icon-trash:hover {background-position : -192px -80px ;} +.active .icon.icon-treeview-corner,.icon.icon-treeview-corner,.icon.icon-treeview-corner:hover {background-position : -224px -240px ;} +.active .icon.icon-treeview-corner-minus,.icon.icon-treeview-corner-minus,.icon.icon-treeview-corner-minus:hover {background-position : -208px -240px ;} +.active .icon.icon-treeview-corner-plus,.icon.icon-treeview-corner-plus,.icon.icon-treeview-corner-plus:hover {background-position : -192px -240px ;} +.active .icon.icon-treeview-vertical-line,.icon.icon-treeview-vertical-line,.icon.icon-treeview-vertical-line:hover {background-position : -240px -240px ;} +.active .icon.icon-triangle-e,.icon.icon-triangle-e,.icon.icon-triangle-e:hover {background-position : -32px 0 ;} +.active .icon.icon-triangle-ew,.icon.icon-triangle-ew,.icon.icon-triangle-ew:hover {background-position : -144px 0 ;} +.active .icon.icon-triangle-n,.icon.icon-triangle-n,.icon.icon-triangle-n:hover {background-position : 0 0 ;} +.active .icon.icon-triangle-ne,.icon.icon-triangle-ne,.icon.icon-triangle-ne:hover {background-position : -16px 0 ;} +.active .icon.icon-triangle-ns,.icon.icon-triangle-ns,.icon.icon-triangle-ns:hover {background-position : -128px 0 ;} +.active .icon.icon-triangle-nw,.icon.icon-triangle-nw,.icon.icon-triangle-nw:hover {background-position : -112px 0 ;} +.active .icon.icon-triangle-s,.icon.icon-triangle-s,.icon.icon-triangle-s:hover {background-position : -64px 0 ;} +.active .icon.icon-triangle-se,.icon.icon-triangle-se,.icon.icon-triangle-se:hover {background-position : -48px 0 ;} +.active .icon.icon-triangle-sw,.icon.icon-triangle-sw,.icon.icon-triangle-sw:hover {background-position : -80px 0 ;} +.active .icon.icon-triangle-w,.icon.icon-triangle-w,.icon.icon-triangle-w:hover {background-position : -96px 0 ;} +.active .icon.icon-undo,.icon.icon-undo,.icon.icon-undo:hover {background-position : -128px -48px ;} +.active .icon.icon-unlink,.icon.icon-unlink,.icon.icon-unlink:hover {background-position : -128px -112px ;} +.active .icon.icon-unlocked,.icon.icon-unlocked,.icon.icon-unlocked:hover {background-position : -48px -96px ;} +.active .icon.icon-user,.icon.icon-user,.icon.icon-user:hover {background-position : -16px -80px ;} +.active .icon.icon-users,.icon.icon-users,.icon.icon-users:hover {background-position : -176px -128px ;} +.active .icon.icon-video,.icon.icon-video,.icon.icon-video:hover {background-position : -192px -128px ;} +.active .icon.icon-volume-off,.icon.icon-volume-off,.icon.icon-volume-off:hover {background-position : -224px -128px ;} +.active .icon.icon-volume-on,.icon.icon-volume-on,.icon.icon-volume-on:hover {background-position : -240px -128px ;} +.active .icon.icon-web,.icon.icon-web,.icon.icon-web:hover {background-position : -144px -112px ;} +.active .icon.icon-wrench,.icon.icon-wrench,.icon.icon-wrench:hover {background-position : -16px -96px ;} +.active .icon.icon-xls,.icon.icon-xls,.icon.icon-xls:hover {background-position : -208px -96px ;} +.active .icon.icon-zoomin,.icon.icon-zoomin,.icon.icon-zoomin:hover {background-position : -208px -64px ;} +.active .icon.icon-zoomout,.icon.icon-zoomout,.icon.icon-zoomout:hover {background-position : -224px -64px ;} +.active .icon32.icon-add,.icon32.icon-add,.icon32.icon-add:hover {background-position : -32px -256px ;} +.active .icon32.icon-alert,.icon32.icon-alert,.icon32.icon-alert:hover {background-position : -128px -256px ;} +.active .icon32.icon-archive,.icon32.icon-archive,.icon32.icon-archive:hover {background-position : -64px -288px ;} +.active .icon32.icon-arrow-4diag,.icon32.icon-arrow-4diag,.icon32.icon-arrow-4diag:hover {background-position : -416px -64px ;} +.active .icon32.icon-arrow-e,.icon32.icon-arrow-e,.icon32.icon-arrow-e:hover {background-position : -64px -64px ;} +.active .icon32.icon-arrow-e-w,.icon32.icon-arrow-e-w,.icon32.icon-arrow-e-w:hover {background-position : -320px -64px ;} +.active .icon32.icon-arrow-n,.icon32.icon-arrow-n,.icon32.icon-arrow-n:hover {background-position : 0 -64px ;} +.active .icon32.icon-arrow-n-s,.icon32.icon-arrow-n-s,.icon32.icon-arrow-n-s:hover {background-position : -256px -64px ;} +.active .icon32.icon-arrow-ne,.icon32.icon-arrow-ne,.icon32.icon-arrow-ne:hover {background-position : -32px -64px ;} +.active .icon32.icon-arrow-ne-sw,.icon32.icon-arrow-ne-sw,.icon32.icon-arrow-ne-sw:hover {background-position : -288px -64px ;} +.active .icon32.icon-arrow-nesw,.icon32.icon-arrow-nesw,.icon32.icon-arrow-nesw:hover {background-position : -384px -64px ;} +.active .icon32.icon-arrow-nw,.icon32.icon-arrow-nw,.icon32.icon-arrow-nw:hover {background-position : -224px -64px ;} +.active .icon32.icon-arrow-s,.icon32.icon-arrow-s,.icon32.icon-arrow-s:hover {background-position : -128px -64px ;} +.active .icon32.icon-arrow-se,.icon32.icon-arrow-se,.icon32.icon-arrow-se:hover {background-position : -96px -64px ;} +.active .icon32.icon-arrow-se-nw,.icon32.icon-arrow-se-nw,.icon32.icon-arrow-se-nw:hover {background-position : -352px -64px ;} +.active .icon32.icon-arrow-sw,.icon32.icon-arrow-sw,.icon32.icon-arrow-sw:hover {background-position : -160px -64px ;} +.active .icon32.icon-arrow-w,.icon32.icon-arrow-w,.icon32.icon-arrow-w:hover {background-position : -192px -64px ;} +.active .icon32.icon-arrowrefresh-e,.icon32.icon-arrowrefresh-e,.icon32.icon-arrowrefresh-e:hover {background-position : -320px -128px ;} +.active .icon32.icon-arrowrefresh-n,.icon32.icon-arrowrefresh-n,.icon32.icon-arrowrefresh-n:hover {background-position : -288px -128px ;} +.active .icon32.icon-arrowrefresh-s,.icon32.icon-arrowrefresh-s,.icon32.icon-arrowrefresh-s:hover {background-position : -352px -128px ;} +.active .icon32.icon-arrowrefresh-w,.icon32.icon-arrowrefresh-w,.icon32.icon-arrowrefresh-w:hover {background-position : -256px -128px ;} +.active .icon32.icon-arrowreturn-en,.icon32.icon-arrowreturn-en,.icon32.icon-arrowreturn-en:hover {background-position : -224px -128px ;} +.active .icon32.icon-arrowreturn-es,.icon32.icon-arrowreturn-es,.icon32.icon-arrowreturn-es:hover {background-position : -160px -128px ;} +.active .icon32.icon-arrowreturn-ne,.icon32.icon-arrowreturn-ne,.icon32.icon-arrowreturn-ne:hover {background-position : -64px -128px ;} +.active .icon32.icon-arrowreturn-nw,.icon32.icon-arrowreturn-nw,.icon32.icon-arrowreturn-nw:hover {background-position : -96px -128px ;} +.active .icon32.icon-arrowreturn-se,.icon32.icon-arrowreturn-se,.icon32.icon-arrowreturn-se:hover {background-position : 0 -128px ;} +.active .icon32.icon-arrowreturn-sw,.icon32.icon-arrowreturn-sw,.icon32.icon-arrowreturn-sw:hover {background-position : -32px -128px ;} +.active .icon32.icon-arrowreturn-wn,.icon32.icon-arrowreturn-wn,.icon32.icon-arrowreturn-wn:hover {background-position : -192px -128px ;} +.active .icon32.icon-arrowreturn-ws,.icon32.icon-arrowreturn-ws,.icon32.icon-arrowreturn-ws:hover {background-position : -128px -128px ;} +.active .icon32.icon-arrowstop-e,.icon32.icon-arrowstop-e,.icon32.icon-arrowstop-e:hover {background-position : -352px 0 ;} +.active .icon32.icon-arrowstop-n,.icon32.icon-arrowstop-n,.icon32.icon-arrowstop-n:hover {background-position : -320px 0 ;} +.active .icon32.icon-arrowstop-s,.icon32.icon-arrowstop-s,.icon32.icon-arrowstop-s:hover {background-position : -384px 0 ;} +.active .icon32.icon-arrowstop-w,.icon32.icon-arrowstop-w,.icon32.icon-arrowstop-w:hover {background-position : -416px 0 ;} +.active .icon32.icon-arrowthick-e,.icon32.icon-arrowthick-e,.icon32.icon-arrowthick-e:hover {background-position : -64px -96px ;} +.active .icon32.icon-arrowthick-n,.icon32.icon-arrowthick-n,.icon32.icon-arrowthick-n:hover {background-position : 0 -96px ;} +.active .icon32.icon-arrowthick-ne,.icon32.icon-arrowthick-ne,.icon32.icon-arrowthick-ne:hover {background-position : -32px -96px ;} +.active .icon32.icon-arrowthick-nw,.icon32.icon-arrowthick-nw,.icon32.icon-arrowthick-nw:hover {background-position : -224px -96px ;} +.active .icon32.icon-arrowthick-s,.icon32.icon-arrowthick-s,.icon32.icon-arrowthick-s:hover {background-position : -128px -96px ;} +.active .icon32.icon-arrowthick-se,.icon32.icon-arrowthick-se,.icon32.icon-arrowthick-se:hover {background-position : -96px -96px ;} +.active .icon32.icon-arrowthick-sw,.icon32.icon-arrowthick-sw,.icon32.icon-arrowthick-sw:hover {background-position : -160px -96px ;} +.active .icon32.icon-arrowthick-w,.icon32.icon-arrowthick-w,.icon32.icon-arrowthick-w:hover {background-position : -192px -96px ;} +.active .icon32.icon-attachment,.icon32.icon-attachment,.icon32.icon-attachment:hover {background-position : -160px -288px ;} +.active .icon32.icon-audio,.icon32.icon-audio,.icon32.icon-audio:hover {background-position : -416px -256px ;} +.active .icon32.icon-basket,.icon32.icon-basket,.icon32.icon-basket:hover {background-position : -288px -256px ;} +.active .icon32.icon-book,.icon32.icon-book,.icon32.icon-book:hover {background-position : -128px -160px ;} +.active .icon32.icon-book-empty,.icon32.icon-book-empty,.icon32.icon-book-empty:hover {background-position : -160px -160px ;} +.active .icon32.icon-bookmark,.icon32.icon-bookmark,.icon32.icon-bookmark:hover {background-position : -288px -160px ;} +.active .icon32.icon-briefcase,.icon32.icon-briefcase,.icon32.icon-briefcase:hover {background-position : -480px -224px ;} +.active .icon32.icon-bullet-off,.icon32.icon-bullet-off,.icon32.icon-bullet-off:hover {background-position : -416px -96px ;} +.active .icon32.icon-bullet-on,.icon32.icon-bullet-on,.icon32.icon-bullet-on:hover {background-position : -384px -96px ;} +.active .icon32.icon-calendar,.icon32.icon-calendar,.icon32.icon-calendar:hover {background-position : -32px -224px ;} +.active .icon32.icon-cancel,.icon32.icon-cancel,.icon32.icon-cancel:hover {background-position : -352px -160px ;} +.active .icon32.icon-carat-1-e,.icon32.icon-carat-1-e,.icon32.icon-carat-1-e:hover {background-position : -64px -32px ;} +.active .icon32.icon-carat-1-n,.icon32.icon-carat-1-n,.icon32.icon-carat-1-n:hover {background-position : 0 -32px ;} +.active .icon32.icon-carat-1-ne,.icon32.icon-carat-1-ne,.icon32.icon-carat-1-ne:hover {background-position : -32px -32px ;} +.active .icon32.icon-carat-1-nw,.icon32.icon-carat-1-nw,.icon32.icon-carat-1-nw:hover {background-position : -224px -32px ;} +.active .icon32.icon-carat-1-s,.icon32.icon-carat-1-s,.icon32.icon-carat-1-s:hover {background-position : -128px -32px ;} +.active .icon32.icon-carat-1-se,.icon32.icon-carat-1-se,.icon32.icon-carat-1-se:hover {background-position : -96px -32px ;} +.active .icon32.icon-carat-1-sw,.icon32.icon-carat-1-sw,.icon32.icon-carat-1-sw:hover {background-position : -160px -32px ;} +.active .icon32.icon-carat-1-w,.icon32.icon-carat-1-w,.icon32.icon-carat-1-w:hover {background-position : -192px -32px ;} +.active .icon32.icon-carat-2-ew,.icon32.icon-carat-2-ew,.icon32.icon-carat-2-ew:hover {background-position : -288px -32px ;} +.active .icon32.icon-carat-2-ns,.icon32.icon-carat-2-ns,.icon32.icon-carat-2-ns:hover {background-position : -256px -32px ;} +.active .icon32.icon-cart,.icon32.icon-cart,.icon32.icon-cart:hover {background-position : -256px -256px ;} +.active .icon32.icon-check,.icon32.icon-check,.icon32.icon-check:hover {background-position : -416px -32px ;} +.active .icon32.icon-clipboard,.icon32.icon-clipboard,.icon32.icon-clipboard:hover {background-position : -160px -192px ;} +.active .icon32.icon-clock,.icon32.icon-clock,.icon32.icon-clock:hover {background-position : -64px -224px ;} +.active .icon32.icon-close,.icon32.icon-close,.icon32.icon-close:hover {background-position : -384px -32px ;} +.active .icon32.icon-comment,.icon32.icon-comment,.icon32.icon-comment:hover {background-position : -224px -256px ;} +.active .icon32.icon-comment-text,.icon32.icon-comment-text,.icon32.icon-comment-text:hover {background-position : -160px -256px ;} +.active .icon32.icon-comment-video,.icon32.icon-comment-video,.icon32.icon-comment-video:hover {background-position : -192px -256px ;} +.active .icon32.icon-compose,.icon32.icon-compose,.icon32.icon-compose:hover {background-position : 0 -288px ;} +.active .icon32.icon-contacts,.icon32.icon-contacts,.icon32.icon-contacts:hover {background-position : -352px -224px ;} +.active .icon32.icon-copy,.icon32.icon-copy,.icon32.icon-copy:hover {background-position : -288px -192px ;} +.active .icon32.icon-cross,.icon32.icon-cross,.icon32.icon-cross:hover {background-position : 0 -256px ;} +.active .icon32.icon-date,.icon32.icon-date,.icon32.icon-date:hover {background-position : 0 -224px ;} +.active .icon32.icon-doc,.icon32.icon-doc,.icon32.icon-doc:hover {background-position : -384px -192px ;} +.active .icon32.icon-document,.icon32.icon-document,.icon32.icon-document:hover {background-position : -448px -192px ;} +.active .icon32.icon-edit,.icon32.icon-edit,.icon32.icon-edit:hover {background-position : -224px -192px ;} +.active .icon32.icon-envelope-closed,.icon32.icon-envelope-closed,.icon32.icon-envelope-closed:hover {background-position : -96px -224px ;} +.active .icon32.icon-envelope-open,.icon32.icon-envelope-open,.icon32.icon-envelope-open:hover {background-position : -128px -224px ;} +.active .icon32.icon-extlink,.icon32.icon-extlink,.icon32.icon-extlink:hover {background-position : -480px -64px ;} +.active .icon32.icon-flag,.icon32.icon-flag,.icon32.icon-flag:hover {background-position : -256px -160px ;} +.active .icon32.icon-folder-collapsed,.icon32.icon-folder-collapsed,.icon32.icon-folder-collapsed:hover {background-position : -192px -160px ;} +.active .icon32.icon-folder-open,.icon32.icon-folder-open,.icon32.icon-folder-open:hover {background-position : -224px -160px ;} +.active .icon32.icon-gear,.icon32.icon-gear,.icon32.icon-gear:hover {background-position : 0 -192px ;} +.active .icon32.icon-globe,.icon32.icon-globe,.icon32.icon-globe:hover {background-position : -320px -224px ;} +.active .icon32.icon-heart,.icon32.icon-heart,.icon32.icon-heart:hover {background-position : -320px -160px ;} +.active .icon32.icon-help,.icon32.icon-help,.icon32.icon-help:hover {background-position : -448px -32px ;} +.active .icon32.icon-home,.icon32.icon-home,.icon32.icon-home:hover {background-position : 0 -160px ;} +.active .icon32.icon-image,.icon32.icon-image,.icon32.icon-image:hover {background-position : -416px -224px ;} +.active .icon32.icon-inbox,.icon32.icon-inbox,.icon32.icon-inbox:hover {background-position : -32px -288px ;} +.active .icon32.icon-info,.icon32.icon-info,.icon32.icon-info:hover {background-position : -96px -256px ;} +.active .icon32.icon-key,.icon32.icon-key,.icon32.icon-key:hover {background-position : -128px -192px ;} +.active .icon32.icon-lightbulb,.icon32.icon-lightbulb,.icon32.icon-lightbulb:hover {background-position : -480px -160px ;} +.active .icon32.icon-link,.icon32.icon-link,.icon32.icon-link:hover {background-position : -224px -224px ;} +.active .icon32.icon-locked,.icon32.icon-locked,.icon32.icon-locked:hover {background-position : -64px -192px ;} +.active .icon32.icon-mail-closed,.icon32.icon-mail-closed,.icon32.icon-mail-closed:hover {background-position : -160px -224px ;} +.active .icon32.icon-mail-open,.icon32.icon-mail-open,.icon32.icon-mail-open:hover {background-position : -192px -224px ;} +.active .icon32.icon-messages,.icon32.icon-messages,.icon32.icon-messages:hover {background-position : -320px -256px ;} +.active .icon32.icon-minus,.icon32.icon-minus,.icon32.icon-minus:hover {background-position : -352px -32px ;} +.active .icon32.icon-newwin,.icon32.icon-newwin,.icon32.icon-newwin:hover {background-position : -448px -64px ;} +.active .icon32.icon-note,.icon32.icon-note,.icon32.icon-note:hover {background-position : -320px -192px ;} +.active .icon32.icon-notice,.icon32.icon-notice,.icon32.icon-notice:hover {background-position : -480px -32px ;} +.active .icon32.icon-page,.icon32.icon-page,.icon32.icon-page:hover {background-position : -256px -192px ;} +.active .icon32.icon-pdf,.icon32.icon-pdf,.icon32.icon-pdf:hover {background-position : -352px -192px ;} +.active .icon32.icon-pin,.icon32.icon-pin,.icon32.icon-pin:hover {background-position : -416px -160px ;} +.active .icon32.icon-plus,.icon32.icon-plus,.icon32.icon-plus:hover {background-position : -320px -32px ;} +.active .icon32.icon-print,.icon32.icon-print,.icon32.icon-print:hover {background-position : -64px -160px ;} +.active .icon32.icon-profile,.icon32.icon-profile,.icon32.icon-profile:hover {background-position : -384px -224px ;} +.active .icon32.icon-redo,.icon32.icon-redo,.icon32.icon-redo:hover {background-position : -288px -96px ;} +.active .icon32.icon-refresh,.icon32.icon-refresh,.icon32.icon-refresh:hover {background-position : -352px -96px ;} +.active .icon32.icon-remove,.icon32.icon-remove,.icon32.icon-remove:hover {background-position : -64px -256px ;} +.active .icon32.icon-reply,.icon32.icon-reply,.icon32.icon-reply:hover {background-position : -96px -288px ;} +.active .icon32.icon-replyall,.icon32.icon-replyall,.icon32.icon-replyall:hover {background-position : -320px -96px ;} +.active .icon32.icon-rssfeed,.icon32.icon-rssfeed,.icon32.icon-rssfeed:hover {background-position : -480px -128px ;} +.active .icon32.icon-save,.icon32.icon-save,.icon32.icon-save:hover {background-position : -96px -160px ;} +.active .icon32.icon-scissors,.icon32.icon-scissors,.icon32.icon-scissors:hover {background-position : -192px -192px ;} +.active .icon32.icon-script,.icon32.icon-script,.icon32.icon-script:hover {background-position : -480px -192px ;} +.active .icon32.icon-search,.icon32.icon-search,.icon32.icon-search:hover {background-position : -384px -128px ;} +.active .icon32.icon-sent,.icon32.icon-sent,.icon32.icon-sent:hover {background-position : -128px -288px ;} +.active .icon32.icon-shuffle,.icon32.icon-shuffle,.icon32.icon-shuffle:hover {background-position : -480px 0 ;} +.active .icon32.icon-square-minus,.icon32.icon-square-minus,.icon32.icon-square-minus:hover {background-position : -352px -480px ;} +.active .icon32.icon-square-plus,.icon32.icon-square-plus,.icon32.icon-square-plus:hover {background-position : -320px -480px ;} +.active .icon32.icon-star-off,.icon32.icon-star-off,.icon32.icon-star-off:hover {background-position : -480px -96px ;} +.active .icon32.icon-star-on,.icon32.icon-star-on,.icon32.icon-star-on:hover {background-position : -448px -96px ;} +.active .icon32.icon-suitcase,.icon32.icon-suitcase,.icon32.icon-suitcase:hover {background-position : -448px -224px ;} +.active .icon32.icon-tag,.icon32.icon-tag,.icon32.icon-tag:hover {background-position : -448px -160px ;} +.active .icon32.icon-transfer-ew,.icon32.icon-transfer-ew,.icon32.icon-transfer-ew:hover {background-position : -448px 0 ;} +.active .icon32.icon-trash,.icon32.icon-trash,.icon32.icon-trash:hover {background-position : -384px -160px ;} +.active .icon32.icon-treeview-corner,.icon32.icon-treeview-corner,.icon32.icon-treeview-corner:hover {background-position : -448px -480px ;} +.active .icon32.icon-treeview-corner-minus,.icon32.icon-treeview-corner-minus,.icon32.icon-treeview-corner-minus:hover {background-position : -416px -480px ;} +.active .icon32.icon-treeview-corner-plus,.icon32.icon-treeview-corner-plus,.icon32.icon-treeview-corner-plus:hover {background-position : -384px -480px ;} +.active .icon32.icon-treeview-vertical-line,.icon32.icon-treeview-vertical-line,.icon32.icon-treeview-vertical-line:hover {background-position : -480px -480px ;} +.active .icon32.icon-triangle-e,.icon32.icon-triangle-e,.icon32.icon-triangle-e:hover {background-position : -64px 0 ;} +.active .icon32.icon-triangle-ew,.icon32.icon-triangle-ew,.icon32.icon-triangle-ew:hover {background-position : -288px 0 ;} +.active .icon32.icon-triangle-n,.icon32.icon-triangle-n,.icon32.icon-triangle-n:hover {background-position : 0 0 ;} +.active .icon32.icon-triangle-ne,.icon32.icon-triangle-ne,.icon32.icon-triangle-ne:hover {background-position : -32px 0 ;} +.active .icon32.icon-triangle-ns,.icon32.icon-triangle-ns,.icon32.icon-triangle-ns:hover {background-position : -256px 0 ;} +.active .icon32.icon-triangle-nw,.icon32.icon-triangle-nw,.icon32.icon-triangle-nw:hover {background-position : -224px 0 ;} +.active .icon32.icon-triangle-s,.icon32.icon-triangle-s,.icon32.icon-triangle-s:hover {background-position : -128px 0 ;} +.active .icon32.icon-triangle-se,.icon32.icon-triangle-se,.icon32.icon-triangle-se:hover {background-position : -96px 0 ;} +.active .icon32.icon-triangle-sw,.icon32.icon-triangle-sw,.icon32.icon-triangle-sw:hover {background-position : -160px 0 ;} +.active .icon32.icon-triangle-w,.icon32.icon-triangle-w,.icon32.icon-triangle-w:hover {background-position : -192px 0 ;} +.active .icon32.icon-undo,.icon32.icon-undo,.icon32.icon-undo:hover {background-position : -256px -96px ;} +.active .icon32.icon-unlink,.icon32.icon-unlink,.icon32.icon-unlink:hover {background-position : -256px -224px ;} +.active .icon32.icon-unlocked,.icon32.icon-unlocked,.icon32.icon-unlocked:hover {background-position : -96px -192px ;} +.active .icon32.icon-user,.icon32.icon-user,.icon32.icon-user:hover {background-position : -32px -160px ;} +.active .icon32.icon-users,.icon32.icon-users,.icon32.icon-users:hover {background-position : -352px -256px ;} +.active .icon32.icon-video,.icon32.icon-video,.icon32.icon-video:hover {background-position : -384px -256px ;} +.active .icon32.icon-volume-off,.icon32.icon-volume-off,.icon32.icon-volume-off:hover {background-position : -448px -256px ;} +.active .icon32.icon-volume-on,.icon32.icon-volume-on,.icon32.icon-volume-on:hover {background-position : -480px -256px ;} +.active .icon32.icon-web,.icon32.icon-web,.icon32.icon-web:hover {background-position : -288px -224px ;} +.active .icon32.icon-wrench,.icon32.icon-wrench,.icon32.icon-wrench:hover {background-position : -32px -192px ;} +.active .icon32.icon-xls,.icon32.icon-xls,.icon32.icon-xls:hover {background-position : -416px -192px ;} +.active .icon32.icon-zoomin,.icon32.icon-zoomin,.icon32.icon-zoomin:hover {background-position : -416px -128px ;} +.active .icon32.icon-zoomout,.icon32.icon-zoomout,.icon32.icon-zoomout:hover {background-position : -448px -128px ;} +.icon.icon-black,.icons-black .icon,.icon.icon-darkgray:hover {background-image : url('../img/opa-icons-black16.png') ;} +.icon.icon-blue,.icons-blue .icon {background-image : url('../img/opa-icons-blue16.png') ;} +.icon.icon-color,.icons-color .icon,.active .icon {background-image : url('../img/opa-icons-color16.png') ;} +.icon.icon-green,.icons-green .icon {background-image : url('../img/opa-icons-green16.png') ;} +.icon.icon-orange,.icons-orange .icon {background-image : url('../img/opa-icons-orange16.png') ;} +.icon.icon-red,.icons-red .icon {background-image : url('../img/opa-icons-red16.png') ;} +.icon.icon-white:hover,.icons-white .icon:hover,.icons-gray .icon {background-image : url('../img/opa-icons-gray16.png') ;} +.icon.icon-white,.icons-white .icon {background-image : url('../img/opa-icons-white16.png') ;} +.icon:hover,.icon.icon-darkgray,.icons-darkgray .icon {background-image : url('../img/opa-icons-darkgray16.png') ;} +.icon {background-image : url('../img/opa-icons-gray16.png') ;background-repeat : no-repeat ;display : inline-block ;height : 16px ;vertical-align : text-top ;width : 16px ;} +.icon32.icon-black,.icons-black .icon32,.icon32.icon-darkgray:hover {background-image : url('../img/opa-icons-black32.png') ;} +.icon32.icon-blue,.icons-blue .icon32 {background-image : url('../img/opa-icons-blue32.png') ;} +.icon32.icon-color,.icons-color .icon32,.active .icon32 {background-image : url('../img/opa-icons-color32.png') ;} +.icon32.icon-green,.icons-green .icon32 {background-image : url('../img/opa-icons-green32.png') ;} +.icon32.icon-orange,.icons-orange .icon32 {background-image : url('../img/opa-icons-orange32.png') ;} +.icon32.icon-red,.icons-red .icon32 {background-image : url('../img/opa-icons-red32.png') ;} +.icon32.icon-white:hover,.icons-white .icon32:hover,.icons-gray .icon32 {background-image : url('../img/opa-icons-gray32.png') ;} +.icon32.icon-white,.icons-white .icon32 {background-image : url('../img/opa-icons-white32.png') ;} +.icon32:hover,.icon32.icon-darkgray,.icons-darkgray .icon32 {background-image : url('../img/opa-icons-darkgray32.png') ;} +.icon32 {background-image : url('../img/opa-icons-gray32.png') ;background-repeat : no-repeat ;display : inline-block ;height : 32px ;vertical-align : text-top ;width : 32px ;} + +ul.media-grid li { + text-align: center; +} +.btn.opa-source { + margin-top: 5px; + vertical-align: top; +} + +.subhead { + background-color: #287590; + background-image: -webkit-gradient(linear, left top, left bottom, from(#2C4369), to(#23A1B2)); + background-image: -webkit-linear-gradient(#2C4369, #23A1B2); + background-image: -moz-linear-gradient(#2C4369, #23A1B2); + background-image: -o-linear-gradient(top, #2C4369, #23A1B2); + background-image: -khtml-gradient(linear, left top, left bottom, from(#2C4369), to(#23A1B2)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2C4369', endColorstr='#23A1B2', GradientType=0); +} +.subhead p a { + font-weight: bold; +} +.subhead hr { + border-color:#CCC; +} +ul.icons-list li { + display:inline-block; + margin:6px; +} +.well-gray { + background-color:#CCC; +} +.well-black { + background-color:#333; +} diff --git a/Bench4Q-Web/src/main/webapp/lib/chrisma/img/glyphicons-halflings.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/glyphicons-halflings.png new file mode 100644 index 00000000..79bc568c Binary files /dev/null and b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/glyphicons-halflings.png differ diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-black16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-black16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-black16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-black16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-black32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-black32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-black32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-black32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-blue16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-blue16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-blue16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-blue16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-blue32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-blue32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-blue32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-blue32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-color16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-color16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-color16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-color16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-color32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-color32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-color32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-color32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-darkgray16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-darkgray16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-darkgray16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-darkgray16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-darkgray32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-darkgray32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-darkgray32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-darkgray32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-gray16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-gray16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-gray16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-gray16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-gray32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-gray32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-gray32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-gray32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-green16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-green16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-green16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-green16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-green32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-green32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-green32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-green32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-orange16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-orange16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-orange16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-orange16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-orange32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-orange32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-orange32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-orange32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-red16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-red16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-red16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-red16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-red32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-red32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-red32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-red32.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-white16.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-white16.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-white16.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-white16.png diff --git a/Bench4Q-Web/src/main/webapp/img/opa-icons-white32.png b/Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-white32.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/img/opa-icons-white32.png rename to Bench4Q-Web/src/main/webapp/lib/chrisma/img/opa-icons-white32.png diff --git a/Bench4Q-Web/src/main/webapp/lib/chrisma/js/theme.js b/Bench4Q-Web/src/main/webapp/lib/chrisma/js/theme.js new file mode 100644 index 00000000..12eeb399 --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/chrisma/js/theme.js @@ -0,0 +1,24 @@ +var current_theme = $.cookie('current_theme')==null ? 'cerulean' :$.cookie('current_theme'); +$(document).ready(function(){ + //themes, change CSS with JS + //default theme(CSS) is cerulean, change it if needed + + switch_theme(current_theme); + + $('#themes a[data-value="'+current_theme+'"]').find('i').addClass('icon-ok'); + + $('#themes a').click(function(e){ + e.preventDefault(); + current_theme=$(this).attr('data-value'); + $.cookie('current_theme',current_theme,{expires:365}); + switch_theme(current_theme); + $('#themes i').removeClass('icon-ok'); + $(this).find('i').addClass('icon-ok'); + }); + + + function switch_theme(theme_name) + { + $('#bs-css').attr('href','css/bootstrap-'+theme_name+'.css'); + } +}); \ No newline at end of file diff --git a/Bench4Q-Web/src/main/webapp/css/jsoneditor.css b/Bench4Q-Web/src/main/webapp/lib/jsoneditor/css/jsoneditor.css similarity index 100% rename from Bench4Q-Web/src/main/webapp/css/jsoneditor.css rename to Bench4Q-Web/src/main/webapp/lib/jsoneditor/css/jsoneditor.css diff --git a/Bench4Q-Web/src/main/webapp/images/jsoneditor-icons.png b/Bench4Q-Web/src/main/webapp/lib/jsoneditor/images/jsoneditor-icons.png similarity index 100% rename from Bench4Q-Web/src/main/webapp/images/jsoneditor-icons.png rename to Bench4Q-Web/src/main/webapp/lib/jsoneditor/images/jsoneditor-icons.png diff --git a/Bench4Q-Web/src/main/webapp/lib/jsoneditor/js/jsoneditor.js b/Bench4Q-Web/src/main/webapp/lib/jsoneditor/js/jsoneditor.js new file mode 100644 index 00000000..5da53bfb --- /dev/null +++ b/Bench4Q-Web/src/main/webapp/lib/jsoneditor/js/jsoneditor.js @@ -0,0 +1,6237 @@ +/*! + * jsoneditor.js + * + * @brief + * JSONEditor is a web-based tool to view, edit, and format JSON. + * It shows data a clear, editable treeview. + * + * Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+ + * + * @license + * This json editor is open sourced with the intention to use the editor as + * a component in your own application. Not to just copy and monetize the editor + * as it is. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * Copyright (c) 2011-2013 Jos de Jong, http://jsoneditoronline.org + * + * @author Jos de Jong, + * @version 2.3.5 + * @date 2013-12-09 + */ +(function() { + + /** + * @constructor JSONEditor + * @param {Element} + * container Container element + * @param {Object} + * [options] Object with options. available options: {String} + * mode Editor mode. Available values: 'tree' (default), 'view', + * 'form', 'text', and 'code'. {function} change Callback method, + * triggered on change of contents {Boolean} search Enable search + * box. True by default Only applicable for modes 'tree', 'view', + * and 'form' {Boolean} history Enable history (undo/redo). True + * by default Only applicable for modes 'tree', 'view', and + * 'form' {String} name Field name for the root node. Only + * applicable for modes 'tree', 'view', and 'form' {Number} + * indentation Number of indentation spaces. 4 by default. Only + * applicable for modes 'text' and 'code' + * @param {Object | + * undefined} json JSON object + */ + function JSONEditor(container, options, json) { + if (!(this instanceof JSONEditor)) { + throw new Error('JSONEditor constructor called without "new".'); + } + + // check for unsupported browser (IE8 and older) + var ieVersion = util.getInternetExplorerVersion(); + if (ieVersion != -1 && ieVersion < 9) { + throw new Error('Unsupported browser, IE9 or newer required. ' + + 'Please install the newest version of your browser.'); + } + + if (arguments.length) { + this._create(container, options, json); + } + } + + /** + * Configuration for all registered modes. Example: { tree: { editor: + * TreeEditor, data: 'json' }, text: { editor: TextEditor, data: 'text' } } + * + * @type { Object. } + */ + JSONEditor.modes = {}; + + /** + * Create the JSONEditor + * + * @param {Element} + * container Container element + * @param {Object} + * [options] See description in constructor + * @param {Object | + * undefined} json JSON object + * @private + */ + JSONEditor.prototype._create = function(container, options, json) { + this.container = container; + this.options = options || {}; + this.json = json || {}; + + var mode = this.options.mode || 'tree'; + this.setMode(mode); + }; + + /** + * Detach the editor from the DOM + * + * @private + */ + JSONEditor.prototype._delete = function() { + }; + + /** + * Set JSON object in editor + * + * @param {Object | + * undefined} json JSON data + */ + JSONEditor.prototype.set = function(json) { + this.json = json; + }; + + /** + * Get JSON from the editor + * + * @returns {Object} json + */ + JSONEditor.prototype.get = function() { + return this.json; + }; + + /** + * Set string containing JSON for the editor + * + * @param {String | + * undefined} jsonText + */ + JSONEditor.prototype.setText = function(jsonText) { + this.json = util.parse(jsonText); + }; + + /** + * Get stringified JSON contents from the editor + * + * @returns {String} jsonText + */ + JSONEditor.prototype.getText = function() { + return JSON.stringify(this.json); + }; + + /** + * Set a field name for the root node. + * + * @param {String | + * undefined} name + */ + JSONEditor.prototype.setName = function(name) { + if (!this.options) { + this.options = {}; + } + this.options.name = name; + }; + + /** + * Get the field name for the root node. + * + * @return {String | undefined} name + */ + JSONEditor.prototype.getName = function() { + return this.options && this.options.name; + }; + + /** + * Change the mode of the editor. JSONEditor will be extended with all + * methods needed for the chosen mode. + * + * @param {String} + * mode Available modes: 'tree' (default), 'view', 'form', + * 'text', and 'code'. + */ + JSONEditor.prototype.setMode = function(mode) { + var container = this.container, options = util.extend({}, this.options), data, name; + + options.mode = mode; + var config = JSONEditor.modes[mode]; + if (config) { + try { + if (config.data == 'text') { + // text + name = this.getName(); + data = this.getText(); + + this._delete(); + util.clear(this); + util.extend(this, config.editor.prototype); + this._create(container, options); + + this.setName(name); + this.setText(data); + } else { + // json + name = this.getName(); + data = this.get(); + + this._delete(); + util.clear(this); + util.extend(this, config.editor.prototype); + this._create(container, options); + + this.setName(name); + this.set(data); + } + + if (typeof config.load === 'function') { + try { + config.load.call(this); + } catch (err) { + } + } + } catch (err) { + this._onError(err); + } + } else { + throw new Error('Unknown mode "' + options.mode + '"'); + } + }; + + /** + * Throw an error. If an error callback is configured in options.error, this + * callback will be invoked. Else, a regular error is thrown. + * + * @param {Error} + * err + * @private + */ + JSONEditor.prototype._onError = function(err) { + // TODO: onError is deprecated since version 2.2.0. cleanup some day + if (typeof this.onError === 'function') { + util.log('WARNING: JSONEditor.onError is deprecated. ' + + 'Use options.error instead.'); + this.onError(err); + } + + if (this.options && typeof this.options.error === 'function') { + this.options.error(err); + } else { + throw err; + } + }; + + /** + * @constructor TreeEditor + * @param {Element} + * container Container element + * @param {Object} + * [options] Object with options. available options: {String} + * mode Editor mode. Available values: 'tree' (default), 'view', + * and 'form'. {Boolean} search Enable search box. True by + * default {Boolean} history Enable history (undo/redo). True by + * default {function} change Callback method, triggered on change + * of contents {String} name Field name for the root node. + * @param {Object | + * undefined} json JSON object + */ + function TreeEditor(container, options, json) { + if (!(this instanceof TreeEditor)) { + throw new Error('TreeEditor constructor called without "new".'); + } + + this._create(container, options, json); + } + + /** + * Create the TreeEditor + * + * @param {Element} + * container Container element + * @param {Object} + * [options] See description in constructor + * @param {Object | + * undefined} json JSON object + * @private + */ + TreeEditor.prototype._create = function(container, options, json) { + if (!container) { + throw new Error('No container element provided.'); + } + this.container = container; + this.dom = {}; + this.highlighter = new Highlighter(); + this.selection = undefined; // will hold the last input selection + + this._setOptions(options); + + if (this.options.history && !this.mode.view) { + this.history = new History(this); + } + + this._createFrame(); + this._createTable(); + + this.set(json || {}); + }; + + /** + * Detach the editor from the DOM + * + * @private + */ + TreeEditor.prototype._delete = function() { + if (this.frame && this.container + && this.frame.parentNode == this.container) { + this.container.removeChild(this.frame); + } + }; + + /** + * Initialize and set default options + * + * @param {Object} + * [options] See description in constructor + * @private + */ + TreeEditor.prototype._setOptions = function(options) { + this.options = { + search : true, + history : true, + mode : 'tree', + name : undefined + // field name of root node + }; + + // copy all options + if (options) { + for ( var prop in options) { + if (options.hasOwnProperty(prop)) { + this.options[prop] = options[prop]; + } + } + + // check for deprecated options + if (options['enableSearch']) { + // deprecated since version 1.6.0, 2012-11-03 + this.options.search = options['enableSearch']; + util + .log('WARNING: Option "enableSearch" is deprecated. Use "search" instead.'); + } + if (options['enableHistory']) { + // deprecated since version 1.6.0, 2012-11-03 + this.options.history = options['enableHistory']; + util + .log('WARNING: Option "enableHistory" is deprecated. Use "history" instead.'); + } + if (options['mode'] == 'editor') { + // deprecated since version 2.2.0, 2013-04-30 + this.options.mode = 'tree'; + util + .log('WARNING: Mode "editor" is deprecated. Use "tree" instead.'); + } + if (options['mode'] == 'viewer') { + // deprecated since version 2.2.0, 2013-04-30 + this.options.mode = 'view'; + util + .log('WARNING: Mode "viewer" is deprecated. Use "view" instead.'); + } + } + + // interpret the mode options + this.mode = { + edit : (this.options.mode != 'view' && this.options.mode != 'form'), + view : (this.options.mode == 'view'), + form : (this.options.mode == 'form') + }; + }; + + // node currently being edited + TreeEditor.focusNode = undefined; + + /** + * Set JSON object in editor + * + * @param {Object | + * undefined} json JSON data + * @param {String} + * [name] Optional field name for the root node. Can also be set + * using setName(name). + */ + TreeEditor.prototype.set = function(json, name) { + // adjust field name for root node + if (name) { + // TODO: deprecated since version 2.2.0. Cleanup some day. + util.log('Warning: second parameter "name" is deprecated. ' + + 'Use setName(name) instead.'); + this.options.name = name; + } + + // verify if json is valid JSON, ignore when a function + if (json instanceof Function || (json === undefined)) { + this.clear(); + } else { + this.content.removeChild(this.table); // Take the table offline + + // replace the root node + var params = { + 'field' : this.options.name, + 'value' : json + }; + var node = new Node(this, params); + this._setRoot(node); + + // expand + var recurse = false; + this.node.expand(recurse); + + this.content.appendChild(this.table); // Put the table online + // again + } + + // TODO: maintain history, store last state and previous document + if (this.history) { + this.history.clear(); + } + }; + + /** + * Get JSON object from editor + * + * @return {Object | undefined} json + */ + TreeEditor.prototype.get = function() { + // remove focus from currently edited node + if (TreeEditor.focusNode) { + TreeEditor.focusNode.blur(); + } + + if (this.node) { + return this.node.getValue(); + } else { + return undefined; + } + }; + + /** + * Get the text contents of the TreeEditor + * + * @return {String} jsonText + */ + TreeEditor.prototype.getText = function() { + return JSON.stringify(this.get()); + }; + + /** + * Set the text contents of the TreeEditor + * + * @param {String} + * jsonText + */ + TreeEditor.prototype.setText = function(jsonText) { + this.set(util.parse(jsonText)); + }; + + /** + * Set a field name for the root node. + * + * @param {String | + * undefined} name + */ + TreeEditor.prototype.setName = function(name) { + this.options.name = name; + if (this.node) { + this.node.updateField(this.options.name); + } + }; + + /** + * Get the field name for the root node. + * + * @return {String | undefined} name + */ + TreeEditor.prototype.getName = function() { + return this.options.name; + }; + + /** + * Remove the root node from the editor + */ + TreeEditor.prototype.clear = function() { + if (this.node) { + this.node.collapse(); + this.tbody.removeChild(this.node.getDom()); + delete this.node; + } + }; + + /** + * Set the root node for the json editor + * + * @param {Node} + * node + * @private + */ + TreeEditor.prototype._setRoot = function(node) { + this.clear(); + + this.node = node; + + // append to the dom + this.tbody.appendChild(node.getDom()); + }; + + /** + * Search text in all nodes The nodes will be expanded when the text is + * found one of its childs, else it will be collapsed. Searches are case + * insensitive. + * + * @param {String} + * text + * @return {Object[]} results Array with nodes containing the search results + * The result objects contains fields: - {Node} node, - {String} + * elem the dom element name where the result is found ('field' or + * 'value') + */ + TreeEditor.prototype.search = function(text) { + var results; + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + results = this.node.search(text); + this.content.appendChild(this.table); // Put the table online + // again + } else { + results = []; + } + + return results; + }; + + /** + * Expand all nodes + */ + TreeEditor.prototype.expandAll = function() { + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + this.node.expand(); + this.content.appendChild(this.table); // Put the table online + // again + } + }; + + /** + * Collapse all nodes + */ + TreeEditor.prototype.collapseAll = function() { + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + this.node.collapse(); + this.content.appendChild(this.table); // Put the table online + // again + } + }; + + /** + * The method onChange is called whenever a field or value is changed, + * created, deleted, duplicated, etc. + * + * @param {String} + * action Change action. Available values: "editField", + * "editValue", "changeType", "appendNode", "removeNode", + * "duplicateNode", "moveNode", "expand", "collapse". + * @param {Object} + * params Object containing parameters describing the change. The + * parameters in params depend on the action (for example for + * "editValue" the Node, old value, and new value are provided). + * params contains all information needed to undo or redo the + * action. + * @private + */ + TreeEditor.prototype._onAction = function(action, params) { + // add an action to the history + if (this.history) { + this.history.add(action, params); + } + + // trigger the onChange callback + if (this.options.change) { + try { + this.options.change(); + } catch (err) { + util.log('Error in change callback: ', err); + } + } + }; + + /** + * Start autoscrolling when given mouse position is above the top of the + * editor contents, or below the bottom. + * + * @param {Number} + * mouseY Absolute mouse position in pixels + */ + TreeEditor.prototype.startAutoScroll = function(mouseY) { + var me = this; + var content = this.content; + var top = util.getAbsoluteTop(content); + var height = content.clientHeight; + var bottom = top + height; + var margin = 24; + var interval = 50; // ms + + if ((mouseY < top + margin) && content.scrollTop > 0) { + this.autoScrollStep = ((top + margin) - mouseY) / 3; + } else if (mouseY > bottom - margin + && height + content.scrollTop < content.scrollHeight) { + this.autoScrollStep = ((bottom - margin) - mouseY) / 3; + } else { + this.autoScrollStep = undefined; + } + + if (this.autoScrollStep) { + if (!this.autoScrollTimer) { + this.autoScrollTimer = setInterval(function() { + if (me.autoScrollStep) { + content.scrollTop -= me.autoScrollStep; + } else { + me.stopAutoScroll(); + } + }, interval); + } + } else { + this.stopAutoScroll(); + } + }; + + /** + * Stop auto scrolling. Only applicable when scrolling + */ + TreeEditor.prototype.stopAutoScroll = function() { + if (this.autoScrollTimer) { + clearTimeout(this.autoScrollTimer); + delete this.autoScrollTimer; + } + if (this.autoScrollStep) { + delete this.autoScrollStep; + } + }; + + /** + * Set the focus to an element in the TreeEditor, set text selection, and + * set scroll position. + * + * @param {Object} + * selection An object containing fields: {Element | undefined} + * dom The dom element which has focus {Range | TextRange} range + * A text selection {Number} scrollTop Scroll position + */ + TreeEditor.prototype.setSelection = function(selection) { + if (!selection) { + return; + } + + if ('scrollTop' in selection && this.content) { + // TODO: animated scroll + this.content.scrollTop = selection.scrollTop; + } + if (selection.range) { + util.setSelectionOffset(selection.range); + } + if (selection.dom) { + selection.dom.focus(); + } + }; + + /** + * Get the current focus + * + * @return {Object} selection An object containing fields: {Element | + * undefined} dom The dom element which has focus {Range | + * TextRange} range A text selection {Number} scrollTop Scroll + * position + */ + TreeEditor.prototype.getSelection = function() { + return { + dom : TreeEditor.domFocus, + scrollTop : this.content ? this.content.scrollTop : 0, + range : util.getSelectionOffset() + }; + }; + + /** + * Adjust the scroll position such that given top position is shown at 1/4 + * of the window height. + * + * @param {Number} + * top + * @param {function(boolean)} + * [callback] Callback, executed when animation is finished. The + * callback returns true when animation is finished, or false + * when not. + */ + TreeEditor.prototype.scrollTo = function(top, callback) { + var content = this.content; + if (content) { + var editor = this; + // cancel any running animation + if (editor.animateTimeout) { + clearTimeout(editor.animateTimeout); + delete editor.animateTimeout; + } + if (editor.animateCallback) { + editor.animateCallback(false); + delete editor.animateCallback; + } + + // calculate final scroll position + var height = content.clientHeight; + var bottom = content.scrollHeight - height; + var finalScrollTop = Math + .min(Math.max(top - height / 4, 0), bottom); + + // animate towards the new scroll position + var animate = function() { + var scrollTop = content.scrollTop; + var diff = (finalScrollTop - scrollTop); + if (Math.abs(diff) > 3) { + content.scrollTop += diff / 3; + editor.animateCallback = callback; + editor.animateTimeout = setTimeout(animate, 50); + } else { + // finished + if (callback) { + callback(true); + } + content.scrollTop = finalScrollTop; + delete editor.animateTimeout; + delete editor.animateCallback; + } + }; + animate(); + } else { + if (callback) { + callback(false); + } + } + }; + + /** + * Create main frame + * + * @private + */ + TreeEditor.prototype._createFrame = function() { + // create the frame + this.frame = document.createElement('div'); + this.frame.className = 'jsoneditor'; + this.container.appendChild(this.frame); + + // create one global event listener to handle all events from all nodes + var editor = this; + var onEvent = function(event) { + editor._onEvent(event); + }; + this.frame.onclick = function(event) { + var target = event.target;// || event.srcElement; + + onEvent(event); + + // prevent default submit action of buttons when TreeEditor is + // located + // inside a form + if (target.nodeName == 'BUTTON') { + event.preventDefault(); + } + }; + this.frame.oninput = onEvent; + this.frame.onchange = onEvent; + this.frame.onkeydown = onEvent; + this.frame.onkeyup = onEvent; + this.frame.oncut = onEvent; + this.frame.onpaste = onEvent; + this.frame.onmousedown = onEvent; + this.frame.onmouseup = onEvent; + this.frame.onmouseover = onEvent; + this.frame.onmouseout = onEvent; + // Note: focus and blur events do not propagate, therefore they defined + // using an eventListener with useCapture=true + // see + // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html + util.addEventListener(this.frame, 'focus', onEvent, true); + util.addEventListener(this.frame, 'blur', onEvent, true); + this.frame.onfocusin = onEvent; // for IE + this.frame.onfocusout = onEvent; // for IE + + // create menu + this.menu = document.createElement('div'); + this.menu.className = 'menu'; + this.frame.appendChild(this.menu); + + // create expand all button + var expandAll = document.createElement('button'); + expandAll.className = 'expand-all'; + expandAll.title = 'Expand all fields'; + expandAll.onclick = function() { + editor.expandAll(); + }; + this.menu.appendChild(expandAll); + + // create expand all button + var collapseAll = document.createElement('button'); + collapseAll.title = 'Collapse all fields'; + collapseAll.className = 'collapse-all'; + collapseAll.onclick = function() { + editor.collapseAll(); + }; + this.menu.appendChild(collapseAll); + + // create undo/redo buttons + if (this.history) { + // create undo button + var undo = document.createElement('button'); + undo.className = 'undo separator'; + undo.title = 'Undo last action (Ctrl+Z)'; + undo.onclick = function() { + editor._onUndo(); + }; + this.menu.appendChild(undo); + this.dom.undo = undo; + + // create redo button + var redo = document.createElement('button'); + redo.className = 'redo'; + redo.title = 'Redo (Ctrl+Shift+Z)'; + redo.onclick = function() { + editor._onRedo(); + }; + this.menu.appendChild(redo); + this.dom.redo = redo; + + // register handler for onchange of history + this.history.onChange = function() { + undo.disabled = !editor.history.canUndo(); + redo.disabled = !editor.history.canRedo(); + }; + this.history.onChange(); + } + + // create mode box + if (this.options && this.options.modes && this.options.modes.length) { + var modeBox = createModeBox(this, this.options.modes, + this.options.mode); + this.menu.appendChild(modeBox); + this.dom.modeBox = modeBox; + } + + // create search box + if (this.options.search) { + this.searchBox = new SearchBox(this, this.menu); + } + }; + + /** + * Perform an undo action + * + * @private + */ + TreeEditor.prototype._onUndo = function() { + if (this.history) { + // undo last action + this.history.undo(); + + // trigger change callback + if (this.options.change) { + this.options.change(); + } + } + }; + + /** + * Perform a redo action + * + * @private + */ + TreeEditor.prototype._onRedo = function() { + if (this.history) { + // redo last action + this.history.redo(); + + // trigger change callback + if (this.options.change) { + this.options.change(); + } + } + }; + + /** + * Event handler + * + * @param event + * @private + */ + TreeEditor.prototype._onEvent = function(event) { + var target = event.target; + + if (event.type == 'keydown') { + this._onKeyDown(event); + } + + if (event.type == 'focus') { + TreeEditor.domFocus = target; + } + + var node = Node.getNodeFromTarget(target); + if (node) { + node.onEvent(event); + } + }; + + /** + * Event handler for keydown. Handles shortcut keys + * + * @param {Event} + * event + * @private + */ + TreeEditor.prototype._onKeyDown = function(event) { + var keynum = event.which || event.keyCode; + var ctrlKey = event.ctrlKey; + var shiftKey = event.shiftKey; + var handled = false; + + if (keynum == 9) { // Tab or Shift+Tab + setTimeout(function() { + // select all text when moving focus to an editable div + util.selectContentEditable(TreeEditor.domFocus); + }, 0); + } + + if (this.searchBox) { + if (ctrlKey && keynum == 70) { // Ctrl+F + this.searchBox.dom.search.focus(); + this.searchBox.dom.search.select(); + handled = true; + } else if (keynum == 114 || (ctrlKey && keynum == 71)) { // F3 or + // Ctrl+G + var focus = true; + if (!shiftKey) { + // select next search result (F3 or Ctrl+G) + this.searchBox.next(focus); + } else { + // select previous search result (Shift+F3 or Ctrl+Shift+G) + this.searchBox.previous(focus); + } + + handled = true; + } + } + + if (this.history) { + if (ctrlKey && !shiftKey && keynum == 90) { // Ctrl+Z + // undo + this._onUndo(); + handled = true; + } else if (ctrlKey && shiftKey && keynum == 90) { // Ctrl+Shift+Z + // redo + this._onRedo(); + handled = true; + } + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }; + + /** + * Create main table + * + * @private + */ + TreeEditor.prototype._createTable = function() { + var contentOuter = document.createElement('div'); + contentOuter.className = 'outer'; + this.contentOuter = contentOuter; + + this.content = document.createElement('div'); + this.content.className = 'tree'; + contentOuter.appendChild(this.content); + + this.table = document.createElement('table'); + this.table.className = 'tree'; + this.content.appendChild(this.table); + + // create colgroup where the first two columns don't have a fixed + // width, and the edit columns do have a fixed width + var col; + this.colgroupContent = document.createElement('colgroup'); + if (this.mode.edit) { + col = document.createElement('col'); + col.width = "24px"; + this.colgroupContent.appendChild(col); + } + col = document.createElement('col'); + col.width = "24px"; + this.colgroupContent.appendChild(col); + col = document.createElement('col'); + this.colgroupContent.appendChild(col); + this.table.appendChild(this.colgroupContent); + + this.tbody = document.createElement('tbody'); + this.table.appendChild(this.tbody); + + this.frame.appendChild(contentOuter); + }; + + // register modes at the JSONEditor + JSONEditor.modes.tree = { + editor : TreeEditor, + data : 'json' + }; + JSONEditor.modes.view = { + editor : TreeEditor, + data : 'json' + }; + JSONEditor.modes.form = { + editor : TreeEditor, + data : 'json' + }; + // Deprecated modes (deprecated since version 2.2.0) + JSONEditor.modes.editor = { + editor : TreeEditor, + data : 'json' + }; + JSONEditor.modes.viewer = { + editor : TreeEditor, + data : 'json' + }; + + /** + * Create a TextEditor and attach it to given container + * + * @constructor TextEditor + * @param {Element} + * container + * @param {Object} + * [options] Object with options. available options: {String} + * mode Available values: "text" (default) or "code". {Number} + * indentation Number of indentation spaces. 4 by default. + * {function} change Callback method triggered on change + * @param {JSON | + * String} [json] initial contents of the formatter + */ + function TextEditor(container, options, json) { + if (!(this instanceof TextEditor)) { + throw new Error('TextEditor constructor called without "new".'); + } + + this._create(container, options, json); + } + + /** + * Create a TextEditor and attach it to given container + * + * @constructor TextEditor + * @param {Element} + * container + * @param {Object} + * [options] See description in constructor + * @param {JSON | + * String} [json] initial contents of the formatter + * @private + */ + TextEditor.prototype._create = function(container, options, json) { + // read options + options = options || {}; + this.options = options; + if (options.indentation) { + this.indentation = Number(options.indentation); + } else { + this.indentation = 2; // number of spaces + } + this.mode = (options.mode == 'code') ? 'code' : 'text'; + if (this.mode == 'code') { + // verify whether Ace editor is available and supported + if (typeof ace === 'undefined') { + this.mode = 'text'; + util + .log('WARNING: Cannot load code editor, Ace library not loaded. ' + + 'Falling back to plain text editor'); + } + } + + var me = this; + this.container = container; + this.dom = {}; + this.editor = undefined; // ace code editor + this.textarea = undefined; // plain text editor (fallback when Ace is + // not + // available) + + this.width = container.clientWidth; + this.height = container.clientHeight; + + this.frame = document.createElement('div'); + this.frame.className = 'jsoneditor'; + this.frame.onclick = function(event) { + // prevent default submit action when TextEditor is located inside a + // form + event.preventDefault(); + }; + + // create menu + this.menu = document.createElement('div'); + this.menu.className = 'menu'; + this.frame.appendChild(this.menu); + + // create format button + var buttonFormat = document.createElement('button'); + buttonFormat.className = 'format'; + buttonFormat.title = 'Format JSON data, with proper indentation and line feeds'; + this.menu.appendChild(buttonFormat); + buttonFormat.onclick = function() { + try { + me.format(); + } catch (err) { + me._onError(err); + } + }; + + // create compact button + var buttonCompact = document.createElement('button'); + buttonCompact.className = 'compact'; + buttonCompact.title = 'Compact JSON data, remove all whitespaces'; + this.menu.appendChild(buttonCompact); + buttonCompact.onclick = function() { + try { + me.compact(); + } catch (err) { + me._onError(err); + } + }; + + // create mode box + if (this.options && this.options.modes && this.options.modes.length) { + var modeBox = createModeBox(this, this.options.modes, + this.options.mode); + this.menu.appendChild(modeBox); + this.dom.modeBox = modeBox; + } + + this.content = document.createElement('div'); + this.content.className = 'outer'; + this.frame.appendChild(this.content); + + this.container.appendChild(this.frame); + + if (this.mode == 'code') { + this.editorDom = document.createElement('div'); + this.editorDom.style.height = '100%'; // TODO: move to css + this.editorDom.style.width = '100%'; // TODO: move to css + this.content.appendChild(this.editorDom); + + var editor = ace.edit(this.editorDom); + editor.setTheme('ace/theme/jsoneditor'); + editor.setShowPrintMargin(false); + editor.setFontSize(13); + editor.getSession().setMode('ace/mode/json'); + editor.getSession().setUseSoftTabs(true); + editor.getSession().setUseWrapMode(true); + this.editor = editor; + + if (options.change) { + // register onchange event + editor.on('change', function() { + options.change(); + }); + } + } else { + // load a plain text textarea + var textarea = document.createElement('textarea'); + textarea.className = 'text'; + textarea.spellcheck = false; + this.content.appendChild(textarea); + this.textarea = textarea; + + if (options.change) { + // register onchange event + if (this.textarea.oninput === null) { + this.textarea.oninput = function() { + options.change(); + } + } else { + // oninput is undefined. For IE8- + this.textarea.onchange = function() { + options.change(); + } + } + } + } + + // load initial json object or string + if (typeof (json) == 'string') { + this.setText(json); + } else { + this.set(json); + } + }; + + /** + * Detach the editor from the DOM + * + * @private + */ + TextEditor.prototype._delete = function() { + if (this.frame && this.container + && this.frame.parentNode == this.container) { + this.container.removeChild(this.frame); + } + }; + + /** + * Throw an error. If an error callback is configured in options.error, this + * callback will be invoked. Else, a regular error is thrown. + * + * @param {Error} + * err + * @private + */ + TextEditor.prototype._onError = function(err) { + // TODO: onError is deprecated since version 2.2.0. cleanup some day + if (typeof this.onError === 'function') { + util.log('WARNING: JSONEditor.onError is deprecated. ' + + 'Use options.error instead.'); + this.onError(err); + } + + if (this.options && typeof this.options.error === 'function') { + this.options.error(err); + } else { + throw err; + } + }; + + /** + * Compact the code in the formatter + */ + TextEditor.prototype.compact = function() { + var json = util.parse(this.getText()); + this.setText(JSON.stringify(json)); + }; + + /** + * Format the code in the formatter + */ + TextEditor.prototype.format = function() { + var json = util.parse(this.getText()); + this.setText(JSON.stringify(json, null, this.indentation)); + }; + + /** + * Set focus to the formatter + */ + TextEditor.prototype.focus = function() { + if (this.textarea) { + this.textarea.focus(); + } + if (this.editor) { + this.editor.focus(); + } + }; + + /** + * Resize the formatter + */ + TextEditor.prototype.resize = function() { + if (this.editor) { + var force = false; + this.editor.resize(force); + } + }; + + /** + * Set json data in the formatter + * + * @param {Object} + * json + */ + TextEditor.prototype.set = function(json) { + this.setText(JSON.stringify(json, null, this.indentation)); + }; + + /** + * Get json data from the formatter + * + * @return {Object} json + */ + TextEditor.prototype.get = function() { + return util.parse(this.getText()); + }; + + /** + * Get the text contents of the TextEditor + * + * @return {String} jsonText + */ + TextEditor.prototype.getText = function() { + if (this.textarea) { + return this.textarea.value; + } + if (this.editor) { + return this.editor.getValue(); + } + return ''; + }; + + /** + * Set the text contents of the TextEditor + * + * @param {String} + * jsonText + */ + TextEditor.prototype.setText = function(jsonText) { + if (this.textarea) { + this.textarea.value = jsonText; + } + if (this.editor) { + this.editor.setValue(jsonText, -1); + } + }; + + // register modes at the JSONEditor + JSONEditor.modes.text = { + editor : TextEditor, + data : 'text', + load : TextEditor.prototype.format + }; + JSONEditor.modes.code = { + editor : TextEditor, + data : 'text', + load : TextEditor.prototype.format + }; + + /** + * @constructor Node Create a new Node + * @param {TreeEditor} + * editor + * @param {Object} + * [params] Can contain parameters: {string} field {boolean} + * fieldEditable {*} value {String} type Can have values 'auto', + * 'array', 'object', or 'string'. + */ + function Node(editor, params) { + /** @type {TreeEditor} */ + this.editor = editor; + this.dom = {}; + this.expanded = false; + + if (params && (params instanceof Object)) { + this.setField(params.field, params.fieldEditable); + this.setValue(params.value, params.type); + } else { + this.setField(''); + this.setValue(null); + } + } + ; + + /** + * Set parent node + * + * @param {Node} + * parent + */ + Node.prototype.setParent = function(parent) { + this.parent = parent; + }; + + /** + * Set field + * + * @param {String} + * field + * @param {boolean} + * [fieldEditable] + */ + Node.prototype.setField = function(field, fieldEditable) { + this.field = field; + this.fieldEditable = (fieldEditable == true); + }; + + /** + * Get field + * + * @return {String} + */ + Node.prototype.getField = function() { + if (this.field === undefined) { + this._getDomField(); + } + + return this.field; + }; + + /** + * Set value. Value is a JSON structure or an element String, Boolean, etc. + * + * @param {*} + * value + * @param {String} + * [type] Specify the type of the value. Can be 'auto', 'array', + * 'object', or 'string' + */ + Node.prototype.setValue = function(value, type) { + var childValue, child; + + // first clear all current childs (if any) + var childs = this.childs; + if (childs) { + while (childs.length) { + this.removeChild(childs[0]); + } + } + + // TODO: remove the DOM of this Node + + this.type = this._getType(value); + + // check if type corresponds with the provided type + if (type && type != this.type) { + if (type == 'string' && this.type == 'auto') { + this.type = type; + } else { + throw new Error('Type mismatch: ' + + 'cannot cast value of type "' + this.type + + ' to the specified type "' + type + '"'); + } + } + + if (this.type == 'array') { + // array + this.childs = []; + for ( var i = 0, iMax = value.length; i < iMax; i++) { + childValue = value[i]; + if (childValue !== undefined + && !(childValue instanceof Function)) { + // ignore undefined and functions + child = new Node(this.editor, { + 'value' : childValue + }); + this.appendChild(child); + } + } + this.value = ''; + } else if (this.type == 'object') { + // object + this.childs = []; + for ( var childField in value) { + if (value.hasOwnProperty(childField)) { + childValue = value[childField]; + if (childValue !== undefined + && !(childValue instanceof Function)) { + // ignore undefined and functions + child = new Node(this.editor, { + 'field' : childField, + 'value' : childValue + }); + this.appendChild(child); + } + } + } + this.value = ''; + } else { + // value + this.childs = undefined; + this.value = value; + /* + * TODO if (typeof(value) == 'string') { var escValue = + * JSON.stringify(value); this.value = escValue.substring(1, + * escValue.length - 1); util.log('check', value, this.value); } + * else { this.value = value; } + */ + } + }; + + /** + * Get value. Value is a JSON structure + * + * @return {*} value + */ + Node.prototype.getValue = function() { + // var childs, i, iMax; + + if (this.type == 'array') { + var arr = []; + this.childs.forEach(function(child) { + arr.push(child.getValue()); + }); + return arr; + } else if (this.type == 'object') { + var obj = {}; + this.childs.forEach(function(child) { + obj[child.getField()] = child.getValue(); + }); + return obj; + } else { + if (this.value === undefined) { + this._getDomValue(); + } + + return this.value; + } + }; + + /** + * Get the nesting level of this node + * + * @return {Number} level + */ + Node.prototype.getLevel = function() { + return (this.parent ? this.parent.getLevel() + 1 : 0); + }; + + /** + * Create a clone of a node The complete state of a clone is copied, + * including whether it is expanded or not. The DOM elements are not cloned. + * + * @return {Node} clone + */ + Node.prototype.clone = function() { + var clone = new Node(this.editor); + clone.type = this.type; + clone.field = this.field; + clone.fieldInnerText = this.fieldInnerText; + clone.fieldEditable = this.fieldEditable; + clone.value = this.value; + clone.valueInnerText = this.valueInnerText; + clone.expanded = this.expanded; + + if (this.childs) { + // an object or array + var cloneChilds = []; + this.childs.forEach(function(child) { + var childClone = child.clone(); + childClone.setParent(clone); + cloneChilds.push(childClone); + }); + clone.childs = cloneChilds; + } else { + // a value + clone.childs = undefined; + } + + return clone; + }; + + /** + * Expand this node and optionally its childs. + * + * @param {boolean} + * [recurse] Optional recursion, true by default. When true, all + * childs will be expanded recursively + */ + Node.prototype.expand = function(recurse) { + if (!this.childs) { + return; + } + + // set this node expanded + this.expanded = true; + if (this.dom.expand) { + this.dom.expand.className = 'expanded'; + } + + this.showChilds(); + + if (recurse != false) { + this.childs.forEach(function(child) { + child.expand(recurse); + }); + } + }; + + /** + * Collapse this node and optionally its childs. + * + * @param {boolean} + * [recurse] Optional recursion, true by default. When true, all + * childs will be collapsed recursively + */ + Node.prototype.collapse = function(recurse) { + if (!this.childs) { + return; + } + + this.hideChilds(); + + // collapse childs in case of recurse + if (recurse != false) { + this.childs.forEach(function(child) { + child.collapse(recurse); + }); + + } + + // make this node collapsed + if (this.dom.expand) { + this.dom.expand.className = 'collapsed'; + } + this.expanded = false; + }; + + /** + * Recursively show all childs when they are expanded + */ + Node.prototype.showChilds = function() { + var childs = this.childs; + if (!childs) { + return; + } + if (!this.expanded) { + return; + } + + var tr = this.dom.tr; + var table = tr ? tr.parentNode : undefined; + if (table) { + // show row with append button + var append = this.getAppend(); + var nextTr = tr.nextSibling; + if (nextTr) { + table.insertBefore(append, nextTr); + } else { + table.appendChild(append); + } + + // show childs + this.childs.forEach(function(child) { + table.insertBefore(child.getDom(), append); + child.showChilds(); + }); + } + }; + + /** + * Hide the node with all its childs + */ + Node.prototype.hide = function() { + var tr = this.dom.tr; + var table = tr ? tr.parentNode : undefined; + if (table) { + table.removeChild(tr); + } + this.hideChilds(); + }; + + /** + * Recursively hide all childs + */ + Node.prototype.hideChilds = function() { + var childs = this.childs; + if (!childs) { + return; + } + if (!this.expanded) { + return; + } + + // hide append row + var append = this.getAppend(); + if (append.parentNode) { + append.parentNode.removeChild(append); + } + + // hide childs + this.childs.forEach(function(child) { + child.hide(); + }); + }; + + /** + * Add a new child to the node. Only applicable when Node value is of type + * array or object + * + * @param {Node} + * node + */ + Node.prototype.appendChild = function(node) { + if (this._hasChilds()) { + // adjust the link to the parent + node.setParent(this); + node.fieldEditable = (this.type == 'object'); + if (this.type == 'array') { + node.index = this.childs.length; + } + this.childs.push(node); + + if (this.expanded) { + // insert into the DOM, before the appendRow + var newTr = node.getDom(); + var appendTr = this.getAppend(); + var table = appendTr ? appendTr.parentNode : undefined; + if (appendTr && table) { + table.insertBefore(newTr, appendTr); + } + + node.showChilds(); + } + + this.updateDom({ + 'updateIndexes' : true + }); + node.updateDom({ + 'recurse' : true + }); + } + }; + + /** + * Move a node from its current parent to this node Only applicable when + * Node value is of type array or object + * + * @param {Node} + * node + * @param {Node} + * beforeNode + */ + Node.prototype.moveBefore = function(node, beforeNode) { + if (this._hasChilds()) { + // create a temporary row, to prevent the scroll position from + // jumping + // when removing the node + var tbody = (this.dom.tr) ? this.dom.tr.parentNode : undefined; + if (tbody) { + var trTemp = document.createElement('tr'); + trTemp.style.height = tbody.clientHeight + 'px'; + tbody.appendChild(trTemp); + } + + if (node.parent) { + node.parent.removeChild(node); + } + + if (beforeNode instanceof AppendNode) { + this.appendChild(node); + } else { + this.insertBefore(node, beforeNode); + } + + if (tbody) { + tbody.removeChild(trTemp); + } + } + }; + + /** + * Move a node from its current parent to this node Only applicable when + * Node value is of type array or object. If index is out of range, the node + * will be appended to the end + * + * @param {Node} + * node + * @param {Number} + * index + */ + Node.prototype.moveTo = function(node, index) { + if (node.parent == this) { + // same parent + var currentIndex = this.childs.indexOf(node); + if (currentIndex < index) { + // compensate the index for removal of the node itself + index++; + } + } + + var beforeNode = this.childs[index] || this.append; + this.moveBefore(node, beforeNode); + }; + + /** + * Insert a new child before a given node Only applicable when Node value is + * of type array or object + * + * @param {Node} + * node + * @param {Node} + * beforeNode + */ + Node.prototype.insertBefore = function(node, beforeNode) { + if (this._hasChilds()) { + if (beforeNode == this.append) { + // append to the child nodes + + // adjust the link to the parent + node.setParent(this); + node.fieldEditable = (this.type == 'object'); + this.childs.push(node); + } else { + // insert before a child node + var index = this.childs.indexOf(beforeNode); + if (index == -1) { + throw new Error('Node not found'); + } + + // adjust the link to the parent + node.setParent(this); + node.fieldEditable = (this.type == 'object'); + this.childs.splice(index, 0, node); + } + + if (this.expanded) { + // insert into the DOM + var newTr = node.getDom(); + var nextTr = beforeNode.getDom(); + var table = nextTr ? nextTr.parentNode : undefined; + if (nextTr && table) { + table.insertBefore(newTr, nextTr); + } + + node.showChilds(); + } + + this.updateDom({ + 'updateIndexes' : true + }); + node.updateDom({ + 'recurse' : true + }); + } + }; + + /** + * Insert a new child before a given node Only applicable when Node value is + * of type array or object + * + * @param {Node} + * node + * @param {Node} + * afterNode + */ + Node.prototype.insertAfter = function(node, afterNode) { + if (this._hasChilds()) { + var index = this.childs.indexOf(afterNode); + var beforeNode = this.childs[index + 1]; + if (beforeNode) { + this.insertBefore(node, beforeNode); + } else { + this.appendChild(node); + } + } + }; + + /** + * Search in this node The node will be expanded when the text is found one + * of its childs, else it will be collapsed. Searches are case insensitive. + * + * @param {String} + * text + * @return {Node[]} results Array with nodes containing the search text + */ + Node.prototype.search = function(text) { + var results = []; + var index; + var search = text ? text.toLowerCase() : undefined; + + // delete old search data + delete this.searchField; + delete this.searchValue; + + // search in field + if (this.field != undefined) { + var field = String(this.field).toLowerCase(); + index = field.indexOf(search); + if (index != -1) { + this.searchField = true; + results.push({ + 'node' : this, + 'elem' : 'field' + }); + } + + // update dom + this._updateDomField(); + } + + // search in value + if (this._hasChilds()) { + // array, object + + // search the nodes childs + if (this.childs) { + var childResults = []; + this.childs.forEach(function(child) { + childResults = childResults.concat(child.search(text)); + }); + results = results.concat(childResults); + } + + // update dom + if (search != undefined) { + var recurse = false; + if (childResults.length == 0) { + this.collapse(recurse); + } else { + this.expand(recurse); + } + } + } else { + // string, auto + if (this.value != undefined) { + var value = String(this.value).toLowerCase(); + index = value.indexOf(search); + if (index != -1) { + this.searchValue = true; + results.push({ + 'node' : this, + 'elem' : 'value' + }); + } + } + + // update dom + this._updateDomValue(); + } + + return results; + }; + + /** + * Move the scroll position such that this node is in the visible area. The + * node will not get the focus + * + * @param {function(boolean)} + * [callback] + */ + Node.prototype.scrollTo = function(callback) { + if (!this.dom.tr || !this.dom.tr.parentNode) { + // if the node is not visible, expand its parents + var parent = this.parent; + var recurse = false; + while (parent) { + parent.expand(recurse); + parent = parent.parent; + } + } + + if (this.dom.tr && this.dom.tr.parentNode) { + this.editor.scrollTo(this.dom.tr.offsetTop, callback); + } + }; + + // stores the element name currently having the focus + Node.focusElement = undefined; + + /** + * Set focus to this node + * + * @param {String} + * [elementName] The field name of the element to get the focus + * available values: 'drag', 'menu', 'expand', 'field', 'value' + * (default) + */ + Node.prototype.focus = function(elementName) { + Node.focusElement = elementName; + + if (this.dom.tr && this.dom.tr.parentNode) { + var dom = this.dom; + + switch (elementName) { + case 'drag': + if (dom.drag) { + dom.drag.focus(); + } else { + dom.menu.focus(); + } + break; + + case 'menu': + dom.menu.focus(); + break; + + case 'expand': + if (this._hasChilds()) { + dom.expand.focus(); + } else if (dom.field && this.fieldEditable) { + dom.field.focus(); + util.selectContentEditable(dom.field); + } else if (dom.value && !this._hasChilds()) { + dom.value.focus(); + util.selectContentEditable(dom.value); + } else { + dom.menu.focus(); + } + break; + + case 'field': + if (dom.field && this.fieldEditable) { + dom.field.focus(); + util.selectContentEditable(dom.field); + } else if (dom.value && !this._hasChilds()) { + dom.value.focus(); + util.selectContentEditable(dom.value); + } else if (this._hasChilds()) { + dom.expand.focus(); + } else { + dom.menu.focus(); + } + break; + + case 'value': + default: + if (dom.value && !this._hasChilds()) { + dom.value.focus(); + util.selectContentEditable(dom.value); + } else if (dom.field && this.fieldEditable) { + dom.field.focus(); + util.selectContentEditable(dom.field); + } else if (this._hasChilds()) { + dom.expand.focus(); + } else { + dom.menu.focus(); + } + break; + } + } + }; + + /** + * Select all text in an editable div after a delay of 0 ms + * + * @param {Element} + * editableDiv + */ + Node.select = function(editableDiv) { + setTimeout(function() { + util.selectContentEditable(editableDiv); + }, 0); + }; + + /** + * Update the values from the DOM field and value of this node + */ + Node.prototype.blur = function() { + // retrieve the actual field and value from the DOM. + this._getDomValue(false); + this._getDomField(false); + }; + + /** + * Duplicate given child node new structure will be added right before the + * cloned node + * + * @param {Node} + * node the childNode to be duplicated + * @return {Node} clone the clone of the node + * @private + */ + Node.prototype._duplicate = function(node) { + var clone = node.clone(); + + /* + * TODO: adjust the field name (to prevent equal field names) if + * (this.type == 'object') { } + */ + + this.insertAfter(clone, node); + + return clone; + }; + + /** + * Check if given node is a child. The method will check recursively to find + * this node. + * + * @param {Node} + * node + * @return {boolean} containsNode + */ + Node.prototype.containsNode = function(node) { + if (this == node) { + return true; + } + + var childs = this.childs; + if (childs) { + // TODO: use the js5 Array.some() here? + for ( var i = 0, iMax = childs.length; i < iMax; i++) { + if (childs[i].containsNode(node)) { + return true; + } + } + } + + return false; + }; + + /** + * Move given node into this node + * + * @param {Node} + * node the childNode to be moved + * @param {Node} + * beforeNode node will be inserted before given node. If no + * beforeNode is given, the node is appended at the end + * @private + */ + Node.prototype._move = function(node, beforeNode) { + if (node == beforeNode) { + // nothing to do... + return; + } + + // check if this node is not a child of the node to be moved here + if (node.containsNode(this)) { + throw new Error('Cannot move a field into a child of itself'); + } + + // remove the original node + if (node.parent) { + node.parent.removeChild(node); + } + + // create a clone of the node + var clone = node.clone(); + node.clearDom(); + + // insert or append the node + if (beforeNode) { + this.insertBefore(clone, beforeNode); + } else { + this.appendChild(clone); + } + + /* + * TODO: adjust the field name (to prevent equal field names) if + * (this.type == 'object') { } + */ + }; + + /** + * Remove a child from the node. Only applicable when Node value is of type + * array or object + * + * @param {Node} + * node The child node to be removed; + * @return {Node | undefined} node The removed node on success, else + * undefined + */ + Node.prototype.removeChild = function(node) { + if (this.childs) { + var index = this.childs.indexOf(node); + + if (index != -1) { + node.hide(); + + // delete old search results + delete node.searchField; + delete node.searchValue; + + var removedNode = this.childs.splice(index, 1)[0]; + + this.updateDom({ + 'updateIndexes' : true + }); + + return removedNode; + } + } + + return undefined; + }; + + /** + * Remove a child node node from this node This method is equal to + * Node.removeChild, except that _remove firex an onChange event. + * + * @param {Node} + * node + * @private + */ + Node.prototype._remove = function(node) { + this.removeChild(node); + }; + + /** + * Change the type of the value of this Node + * + * @param {String} + * newType + */ + Node.prototype.changeType = function(newType) { + var oldType = this.type; + + if (oldType == newType) { + // type is not changed + return; + } + + if ((newType == 'string' || newType == 'auto') + && (oldType == 'string' || oldType == 'auto')) { + // this is an easy change + this.type = newType; + } else { + // change from array to object, or from string/auto to object/array + var table = this.dom.tr ? this.dom.tr.parentNode : undefined; + var lastTr; + if (this.expanded) { + lastTr = this.getAppend(); + } else { + lastTr = this.getDom(); + } + var nextTr = (lastTr && lastTr.parentNode) ? lastTr.nextSibling + : undefined; + + // hide current field and all its childs + this.hide(); + this.clearDom(); + + // adjust the field and the value + this.type = newType; + + // adjust childs + if (newType == 'object') { + if (!this.childs) { + this.childs = []; + } + + this.childs.forEach(function(child, index) { + child.clearDom(); + delete child.index; + child.fieldEditable = true; + if (child.field == undefined) { + child.field = ''; + } + }); + + if (oldType == 'string' || oldType == 'auto') { + this.expanded = true; + } + } else if (newType == 'array') { + if (!this.childs) { + this.childs = []; + } + + this.childs.forEach(function(child, index) { + child.clearDom(); + child.fieldEditable = false; + child.index = index; + }); + + if (oldType == 'string' || oldType == 'auto') { + this.expanded = true; + } + } else { + this.expanded = false; + } + + // create new DOM + if (table) { + if (nextTr) { + table.insertBefore(this.getDom(), nextTr); + } else { + table.appendChild(this.getDom()); + } + } + this.showChilds(); + } + + if (newType == 'auto' || newType == 'string') { + // cast value to the correct type + if (newType == 'string') { + this.value = String(this.value); + } else { + this.value = this._stringCast(String(this.value)); + } + + this.focus(); + } + + this.updateDom({ + 'updateIndexes' : true + }); + }; + + /** + * Retrieve value from DOM + * + * @param {boolean} + * [silent] If true (default), no errors will be thrown in case + * of invalid data + * @private + */ + Node.prototype._getDomValue = function(silent) { + if (this.dom.value && this.type != 'array' && this.type != 'object') { + this.valueInnerText = util.getInnerText(this.dom.value); + } + + if (this.valueInnerText != undefined) { + try { + // retrieve the value + var value; + if (this.type == 'string') { + value = this._unescapeHTML(this.valueInnerText); + } else { + var str = this._unescapeHTML(this.valueInnerText); + value = this._stringCast(str); + } + if (value !== this.value) { + var oldValue = this.value; + this.value = value; + this.editor._onAction('editValue', { + 'node' : this, + 'oldValue' : oldValue, + 'newValue' : value, + 'oldSelection' : this.editor.selection, + 'newSelection' : this.editor.getSelection() + }); + } + } catch (err) { + this.value = undefined; + // TODO: sent an action with the new, invalid value? + if (silent != true) { + throw err; + } + } + } + }; + + /** + * Update dom value: - the text color of the value, depending on the type of + * the value - the height of the field, depending on the width - background + * color in case it is empty + * + * @private + */ + Node.prototype._updateDomValue = function() { + var domValue = this.dom.value; + if (domValue) { + // set text color depending on value type + // TODO: put colors in css + var v = this.value; + var t = (this.type == 'auto') ? util.type(v) : this.type; + var isUrl = (t == 'string' && util.isUrl(v)); + var color = ''; + if (isUrl && !this.editor.mode.edit) { + color = ''; + } else if (t == 'string') { + color = 'green'; + } else if (t == 'number') { + color = 'red'; + } else if (t == 'boolean') { + color = 'darkorange'; + } else if (this._hasChilds()) { + color = ''; + } else if (v === null) { + color = '#004ED0'; // blue + } else { + // invalid value + color = 'black'; + } + domValue.style.color = color; + + // make background color light-gray when empty + var isEmpty = (String(this.value) == '' && this.type != 'array' && this.type != 'object'); + if (isEmpty) { + util.addClassName(domValue, 'empty'); + } else { + util.removeClassName(domValue, 'empty'); + } + + // underline url + if (isUrl) { + util.addClassName(domValue, 'url'); + } else { + util.removeClassName(domValue, 'url'); + } + + // update title + if (t == 'array' || t == 'object') { + var count = this.childs ? this.childs.length : 0; + domValue.title = this.type + ' containing ' + count + ' items'; + } else if (t == 'string' && util.isUrl(v)) { + if (this.editor.mode.edit) { + domValue.title = 'Ctrl+Click or Ctrl+Enter to open url in new window'; + } + } else { + domValue.title = ''; + } + + // highlight when there is a search result + if (this.searchValueActive) { + util.addClassName(domValue, 'highlight-active'); + } else { + util.removeClassName(domValue, 'highlight-active'); + } + if (this.searchValue) { + util.addClassName(domValue, 'highlight'); + } else { + util.removeClassName(domValue, 'highlight'); + } + + // strip formatting from the contents of the editable div + util.stripFormatting(domValue); + } + }; + + /** + * Update dom field: - the text color of the field, depending on the text - + * the height of the field, depending on the width - background color in + * case it is empty + * + * @private + */ + Node.prototype._updateDomField = function() { + var domField = this.dom.field; + if (domField) { + // make backgound color lightgray when empty + var isEmpty = (String(this.field) == '' && this.parent.type != 'array'); + if (isEmpty) { + util.addClassName(domField, 'empty'); + } else { + util.removeClassName(domField, 'empty'); + } + + // highlight when there is a search result + if (this.searchFieldActive) { + util.addClassName(domField, 'highlight-active'); + } else { + util.removeClassName(domField, 'highlight-active'); + } + if (this.searchField) { + util.addClassName(domField, 'highlight'); + } else { + util.removeClassName(domField, 'highlight'); + } + + // strip formatting from the contents of the editable div + util.stripFormatting(domField); + } + }; + + /** + * Retrieve field from DOM + * + * @param {boolean} + * [silent] If true (default), no errors will be thrown in case + * of invalid data + * @private + */ + Node.prototype._getDomField = function(silent) { + if (this.dom.field && this.fieldEditable) { + this.fieldInnerText = util.getInnerText(this.dom.field); + } + + if (this.fieldInnerText != undefined) { + try { + var field = this._unescapeHTML(this.fieldInnerText); + + if (field !== this.field) { + var oldField = this.field; + this.field = field; + this.editor._onAction('editField', { + 'node' : this, + 'oldValue' : oldField, + 'newValue' : field, + 'oldSelection' : this.editor.selection, + 'newSelection' : this.editor.getSelection() + }); + } + } catch (err) { + this.field = undefined; + // TODO: sent an action here, with the new, invalid value? + if (silent != true) { + throw err; + } + } + } + }; + + /** + * Clear the dom of the node + */ + Node.prototype.clearDom = function() { + // TODO: hide the node first? + // this.hide(); + // TODO: recursively clear dom? + + this.dom = {}; + }; + + /** + * Get the HTML DOM TR element of the node. The dom will be generated when + * not yet created + * + * @return {Element} tr HTML DOM TR Element + */ + Node.prototype.getDom = function() { + var dom = this.dom; + if (dom.tr) { + return dom.tr; + } + + // create row + dom.tr = document.createElement('tr'); + dom.tr.node = this; + + if (this.editor.mode.edit) { + // create draggable area + var tdDrag = document.createElement('td'); + if (this.parent) { + var domDrag = document.createElement('button'); + dom.drag = domDrag; + domDrag.className = 'dragarea'; + domDrag.title = 'Drag to move this field (Alt+Shift+Arrows)'; + tdDrag.appendChild(domDrag); + } + dom.tr.appendChild(tdDrag); + + // create context menu + var tdMenu = document.createElement('td'); + var menu = document.createElement('button'); + dom.menu = menu; + menu.className = 'contextmenu'; + menu.title = 'Click to open the actions menu (Ctrl+M)'; + tdMenu.appendChild(dom.menu); + dom.tr.appendChild(tdMenu); + } + + // create tree and field + var tdField = document.createElement('td'); + dom.tr.appendChild(tdField); + dom.tree = this._createDomTree(); + tdField.appendChild(dom.tree); + + this.updateDom({ + 'updateIndexes' : true + }); + + return dom.tr; + }; + + /** + * DragStart event, fired on mousedown on the dragarea at the left side of a + * Node + * + * @param {Event} + * event + * @private + */ + Node.prototype._onDragStart = function(event) { + var node = this; + if (!this.mousemove) { + this.mousemove = util.addEventListener(document, 'mousemove', + function(event) { + node._onDrag(event); + }); + } + + if (!this.mouseup) { + this.mouseup = util.addEventListener(document, 'mouseup', function( + event) { + node._onDragEnd(event); + }); + } + + this.editor.highlighter.lock(); + this.drag = { + 'oldCursor' : document.body.style.cursor, + 'startParent' : this.parent, + 'startIndex' : this.parent.childs.indexOf(this), + 'mouseX' : event.pageX, + 'level' : this.getLevel() + }; + document.body.style.cursor = 'move'; + + event.preventDefault(); + }; + + /** + * Drag event, fired when moving the mouse while dragging a Node + * + * @param {Event} + * event + * @private + */ + Node.prototype._onDrag = function(event) { + // TODO: this method has grown too large. Split it in a number of + // methods + var mouseY = event.pageY; + var mouseX = event.pageX; + + var trThis, trPrev, trNext, trFirst, trLast, trRoot; + var nodePrev, nodeNext; + var topThis, topPrev, topFirst, heightThis, bottomNext, heightNext; + var moved = false; + + // TODO: add an ESC option, which resets to the original position + + // move up/down + trThis = this.dom.tr; + topThis = util.getAbsoluteTop(trThis); + heightThis = trThis.offsetHeight; + if (mouseY < topThis) { + // move up + trPrev = trThis; + do { + trPrev = trPrev.previousSibling; + nodePrev = Node.getNodeFromTarget(trPrev); + topPrev = trPrev ? util.getAbsoluteTop(trPrev) : 0; + } while (trPrev && mouseY < topPrev); + + if (nodePrev && !nodePrev.parent) { + nodePrev = undefined; + } + + if (!nodePrev) { + // move to the first node + trRoot = trThis.parentNode.firstChild; + trPrev = trRoot ? trRoot.nextSibling : undefined; + nodePrev = Node.getNodeFromTarget(trPrev); + if (nodePrev == this) { + nodePrev = undefined; + } + } + + if (nodePrev) { + // check if mouseY is really inside the found node + trPrev = nodePrev.dom.tr; + topPrev = trPrev ? util.getAbsoluteTop(trPrev) : 0; + if (mouseY > topPrev + heightThis) { + nodePrev = undefined; + } + } + + if (nodePrev) { + nodePrev.parent.moveBefore(this, nodePrev); + moved = true; + } + } else { + // move down + trLast = (this.expanded && this.append) ? this.append.getDom() + : this.dom.tr; + trFirst = trLast ? trLast.nextSibling : undefined; + if (trFirst) { + topFirst = util.getAbsoluteTop(trFirst); + trNext = trFirst; + do { + nodeNext = Node.getNodeFromTarget(trNext); + if (trNext) { + bottomNext = trNext.nextSibling ? util + .getAbsoluteTop(trNext.nextSibling) : 0; + heightNext = trNext ? (bottomNext - topFirst) : 0; + + if (nodeNext.parent.childs.length == 1 + && nodeNext.parent.childs[0] == this) { + // We are about to remove the last child of this + // parent, + // which will make the parents appendNode visible. + topThis += 24 - 1; + // TODO: dangerous to suppose the height of the + // appendNode a + // constant of 24-1 px. + } + } + + trNext = trNext.nextSibling; + } while (trNext && mouseY > topThis + heightNext); + + if (nodeNext && nodeNext.parent) { + // calculate the desired level + var diffX = (mouseX - this.drag.mouseX); + var diffLevel = Math.round(diffX / 24 / 2); + var level = this.drag.level + diffLevel; // desired level + var levelNext = nodeNext.getLevel(); // level to be + + // find the best fitting level (move upwards over the append + // nodes) + trPrev = nodeNext.dom.tr.previousSibling; + while (levelNext < level && trPrev) { + nodePrev = Node.getNodeFromTarget(trPrev); + if (nodePrev == this || nodePrev._isChildOf(this)) { + // neglect itself and its childs + } else if (nodePrev instanceof AppendNode) { + var childs = nodePrev.parent.childs; + if (childs.length > 1 + || (childs.length == 1 && childs[0] != this)) { + // non-visible append node of a list of childs + // consisting of not only this node (else the + // append node will change into a visible + // "empty" + // text when removing this node). + nodeNext = Node.getNodeFromTarget(trPrev); + levelNext = nodeNext.getLevel(); + } else { + break; + } + } else { + break; + } + + trPrev = trPrev.previousSibling; + } + + // move the node when its position is changed + if (trLast.nextSibling != nodeNext.dom.tr) { + nodeNext.parent.moveBefore(this, nodeNext); + moved = true; + } + } + } + } + + if (moved) { + // update the dragging parameters when moved + this.drag.mouseX = mouseX; + this.drag.level = this.getLevel(); + } + + // auto scroll when hovering around the top of the editor + this.editor.startAutoScroll(mouseY); + + event.preventDefault(); + }; + + /** + * Drag event, fired on mouseup after having dragged a node + * + * @param {Event} + * event + * @private + */ + Node.prototype._onDragEnd = function(event) { + var params = { + 'node' : this, + 'startParent' : this.drag.startParent, + 'startIndex' : this.drag.startIndex, + 'endParent' : this.parent, + 'endIndex' : this.parent.childs.indexOf(this) + }; + if ((params.startParent != params.endParent) + || (params.startIndex != params.endIndex)) { + // only register this action if the node is actually moved to + // another place + this.editor._onAction('moveNode', params); + } + + document.body.style.cursor = this.drag.oldCursor; + this.editor.highlighter.unlock(); + delete this.drag; + + if (this.mousemove) { + util.removeEventListener(document, 'mousemove', this.mousemove); + delete this.mousemove; + } + if (this.mouseup) { + util.removeEventListener(document, 'mouseup', this.mouseup); + delete this.mouseup; + } + + // Stop any running auto scroll + this.editor.stopAutoScroll(); + + event.preventDefault(); + }; + + /** + * Test if this node is a child of an other node + * + * @param {Node} + * node + * @return {boolean} isChild + * @private + */ + Node.prototype._isChildOf = function(node) { + var n = this.parent; + while (n) { + if (n == node) { + return true; + } + n = n.parent; + } + + return false; + }; + + /** + * Create an editable field + * + * @return {Element} domField + * @private + */ + Node.prototype._createDomField = function() { + return document.createElement('div'); + }; + + /** + * Set highlighting for this node and all its childs. Only applied to the + * currently visible (expanded childs) + * + * @param {boolean} + * highlight + */ + Node.prototype.setHighlight = function(highlight) { + if (this.dom.tr) { + this.dom.tr.className = (highlight ? 'highlight' : ''); + + if (this.append) { + this.append.setHighlight(highlight); + } + + if (this.childs) { + this.childs.forEach(function(child) { + child.setHighlight(highlight); + }); + } + } + }; + + /** + * Update the value of the node. Only primitive types are allowed, no Object + * or Array is allowed. + * + * @param {String | + * Number | Boolean | null} value + */ + Node.prototype.updateValue = function(value) { + this.value = value; + this.updateDom(); + }; + + /** + * Update the field of the node. + * + * @param {String} + * field + */ + Node.prototype.updateField = function(field) { + this.field = field; + this.updateDom(); + }; + + /** + * Update the HTML DOM, optionally recursing through the childs + * + * @param {Object} + * [options] Available parameters: {boolean} [recurse] If true, + * the DOM of the childs will be updated recursively. False by + * default. {boolean} [updateIndexes] If true, the childs indexes + * of the node will be updated too. False by default. + */ + Node.prototype.updateDom = function(options) { + // update level indentation + var domTree = this.dom.tree; + if (domTree) { + domTree.style.marginLeft = this.getLevel() * 24 + 'px'; + } + + // update field + var domField = this.dom.field; + if (domField) { + if (this.fieldEditable == true) { + // parent is an object + domField.contentEditable = this.editor.mode.edit; + domField.spellcheck = false; + domField.className = 'field'; + } else { + // parent is an array this is the root node + domField.className = 'readonly'; + } + + var field; + if (this.index != undefined) { + field = this.index; + } else if (this.field != undefined) { + field = this.field; + } else if (this._hasChilds()) { + field = this.type; + } else { + field = ''; + } + domField.innerHTML = this._escapeHTML(field); + } + + // update value + var domValue = this.dom.value; + if (domValue) { + var count = this.childs ? this.childs.length : 0; + if (this.type == 'array') { + domValue.innerHTML = '[' + count + ']'; + } else if (this.type == 'object') { + domValue.innerHTML = '{' + count + '}'; + } else { + domValue.innerHTML = this._escapeHTML(this.value); + } + } + + // update field and value + this._updateDomField(); + this._updateDomValue(); + + // update childs indexes + if (options && options.updateIndexes == true) { + // updateIndexes is true or undefined + this._updateDomIndexes(); + } + + if (options && options.recurse == true) { + // recurse is true or undefined. update childs recursively + if (this.childs) { + this.childs.forEach(function(child) { + child.updateDom(options); + }); + } + } + + // update row with append button + if (this.append) { + this.append.updateDom(); + } + }; + + /** + * Update the DOM of the childs of a node: update indexes and undefined + * field names. Only applicable when structure is an array or object + * + * @private + */ + Node.prototype._updateDomIndexes = function() { + var domValue = this.dom.value; + var childs = this.childs; + if (domValue && childs) { + if (this.type == 'array') { + childs.forEach(function(child, index) { + child.index = index; + var childField = child.dom.field; + if (childField) { + childField.innerHTML = index; + } + }); + } else if (this.type == 'object') { + childs.forEach(function(child) { + if (child.index != undefined) { + delete child.index; + + if (child.field == undefined) { + child.field = ''; + } + } + }); + } + } + }; + + /** + * Create an editable value + * + * @private + */ + Node.prototype._createDomValue = function() { + var domValue; + + if (this.type == 'array') { + domValue = document.createElement('div'); + domValue.className = 'readonly'; + domValue.innerHTML = '[...]'; + } else if (this.type == 'object') { + domValue = document.createElement('div'); + domValue.className = 'readonly'; + domValue.innerHTML = '{...}'; + } else { + if (!this.editor.mode.edit && util.isUrl(this.value)) { + // create a link in case of read-only editor and value + // containing an url + domValue = document.createElement('a'); + domValue.className = 'value'; + domValue.href = this.value; + domValue.target = '_blank'; + domValue.innerHTML = this._escapeHTML(this.value); + } else { + // create and editable or read-only div + domValue = document.createElement('div'); + domValue.contentEditable = !this.editor.mode.view; + domValue.spellcheck = false; + domValue.className = 'value'; + domValue.innerHTML = this._escapeHTML(this.value); + } + } + + return domValue; + }; + + /** + * Create an expand/collapse button + * + * @return {Element} expand + * @private + */ + Node.prototype._createDomExpandButton = function() { + // create expand button + var expand = document.createElement('button'); + if (this._hasChilds()) { + expand.className = this.expanded ? 'expanded' : 'collapsed'; + expand.title = 'Click to expand/collapse this field (Ctrl+E). \n' + + 'Ctrl+Click to expand/collapse including all childs.'; + } else { + expand.className = 'invisible'; + expand.title = ''; + } + + return expand; + }; + + /** + * Create a DOM tree element, containing the expand/collapse button + * + * @return {Element} domTree + * @private + */ + Node.prototype._createDomTree = function() { + var dom = this.dom; + var domTree = document.createElement('table'); + var tbody = document.createElement('tbody'); + domTree.style.borderCollapse = 'collapse'; // TODO: put in css + domTree.className = 'values'; + domTree.appendChild(tbody); + var tr = document.createElement('tr'); + tbody.appendChild(tr); + + // create expand button + var tdExpand = document.createElement('td'); + tdExpand.className = 'tree'; + tr.appendChild(tdExpand); + dom.expand = this._createDomExpandButton(); + tdExpand.appendChild(dom.expand); + dom.tdExpand = tdExpand; + + // create the field + var tdField = document.createElement('td'); + tdField.className = 'tree'; + tr.appendChild(tdField); + dom.field = this._createDomField(); + tdField.appendChild(dom.field); + dom.tdField = tdField; + + // create a separator + var tdSeparator = document.createElement('td'); + tdSeparator.className = 'tree'; + tr.appendChild(tdSeparator); + if (this.type != 'object' && this.type != 'array') { + tdSeparator.appendChild(document.createTextNode(':')); + tdSeparator.className = 'separator'; + } + dom.tdSeparator = tdSeparator; + + // create the value + var tdValue = document.createElement('td'); + tdValue.className = 'tree'; + tr.appendChild(tdValue); + dom.value = this._createDomValue(); + tdValue.appendChild(dom.value); + dom.tdValue = tdValue; + + return domTree; + }; + + /** + * Handle an event. The event is catched centrally by the editor + * + * @param {Event} + * event + */ + Node.prototype.onEvent = function(event) { + var type = event.type, target = event.target || event.srcElement, dom = this.dom, node = this, focusNode, expandable = this + ._hasChilds(); + + // check if mouse is on menu or on dragarea. + // If so, highlight current row and its childs + if (target == dom.drag || target == dom.menu) { + if (type == 'mouseover') { + this.editor.highlighter.highlight(this); + } else if (type == 'mouseout') { + this.editor.highlighter.unhighlight(); + } + } + + // drag events + if (type == 'mousedown' && target == dom.drag) { + this._onDragStart(event); + } + + // context menu events + if (type == 'click' && target == dom.menu) { + var highlighter = node.editor.highlighter; + highlighter.highlight(node); + highlighter.lock(); + util.addClassName(dom.menu, 'selected'); + this.showContextMenu(dom.menu, function() { + util.removeClassName(dom.menu, 'selected'); + highlighter.unlock(); + highlighter.unhighlight(); + }); + } + + // expand events + if (type == 'click' && target == dom.expand) { + if (expandable) { + var recurse = event.ctrlKey; // with ctrl-key, + // expand/collapse all + this._onExpand(recurse); + } + } + + // value events + var domValue = dom.value; + if (target == domValue) { + // noinspection FallthroughInSwitchStatementJS + switch (type) { + case 'focus': + focusNode = this; + break; + + case 'blur': + case 'change': + this._getDomValue(true); + this._updateDomValue(); + if (this.value) { + domValue.innerHTML = this._escapeHTML(this.value); + } + break; + + case 'input': + this._getDomValue(true); + this._updateDomValue(); + break; + + case 'keydown': + case 'mousedown': + this.editor.selection = this.editor.getSelection(); + break; + + case 'click': + if (event.ctrlKey && this.editor.mode.edit) { + if (util.isUrl(this.value)) { + window.open(this.value, '_blank'); + } + } + break; + + case 'keyup': + this._getDomValue(true); + this._updateDomValue(); + break; + + case 'cut': + case 'paste': + setTimeout(function() { + node._getDomValue(true); + node._updateDomValue(); + }, 1); + break; + } + } + + // field events + var domField = dom.field; + if (target == domField) { + switch (type) { + case 'focus': + focusNode = this; + break; + + case 'blur': + case 'change': + this._getDomField(true); + this._updateDomField(); + if (this.field) { + domField.innerHTML = this._escapeHTML(this.field); + } + break; + + case 'input': + this._getDomField(true); + this._updateDomField(); + break; + + case 'keydown': + case 'mousedown': + this.editor.selection = this.editor.getSelection(); + break; + + case 'keyup': + this._getDomField(true); + this._updateDomField(); + break; + + case 'cut': + case 'paste': + setTimeout(function() { + node._getDomField(true); + node._updateDomField(); + }, 1); + break; + } + } + + // focus + // when clicked in whitespace left or right from the field or value, set + // focus + var domTree = dom.tree; + if (target == domTree.parentNode) { + switch (type) { + case 'click': + var left = (event.offsetX != undefined) ? (event.offsetX < (this + .getLevel() + 1) * 24) + : (event.pageX < util.getAbsoluteLeft(dom.tdSeparator));// for + // FF + if (left || expandable) { + // node is expandable when it is an object or array + if (domField) { + util.setEndOfContentEditable(domField); + domField.focus(); + } + } else { + if (domValue) { + util.setEndOfContentEditable(domValue); + domValue.focus(); + } + } + break; + } + } + if ((target == dom.tdExpand && !expandable) || target == dom.tdField + || target == dom.tdSeparator) { + switch (type) { + case 'click': + if (domField) { + util.setEndOfContentEditable(domField); + domField.focus(); + } + break; + } + } + + if (type == 'keydown') { + this.onKeyDown(event); + } + }; + + /** + * Key down event handler + * + * @param {Event} + * event + */ + Node.prototype.onKeyDown = function(event) { + var keynum = event.which || event.keyCode; + var target = event.target || event.srcElement; + var ctrlKey = event.ctrlKey; + var shiftKey = event.shiftKey; + var altKey = event.altKey; + var handled = false; + var prevNode, nextNode, nextDom, nextDom2; + + // util.log(ctrlKey, keynum, event.charCode); // TODO: cleanup + if (keynum == 13) { // Enter + if (target == this.dom.value) { + if (!this.editor.mode.edit || event.ctrlKey) { + if (util.isUrl(this.value)) { + window.open(this.value, '_blank'); + handled = true; + } + } + } else if (target == this.dom.expand) { + var expandable = this._hasChilds(); + if (expandable) { + var recurse = event.ctrlKey; // with ctrl-key, + // expand/collapse all + this._onExpand(recurse); + target.focus(); + handled = true; + } + } + } else if (keynum == 68) { // D + if (ctrlKey) { // Ctrl+D + this._onDuplicate(); + handled = true; + } + } else if (keynum == 69) { // E + if (ctrlKey) { // Ctrl+E and Ctrl+Shift+E + this._onExpand(shiftKey); // recurse = shiftKey + target.focus(); // TODO: should restore focus in case of + // recursing + // expand (which takes DOM offline) + handled = true; + } + } else if (keynum == 77) { // M + if (ctrlKey) { // Ctrl+M + this.showContextMenu(target); + handled = true; + } + } else if (keynum == 46) { // Del + if (ctrlKey) { // Ctrl+Del + this._onRemove(); + handled = true; + } + } else if (keynum == 45) { // Ins + if (ctrlKey && !shiftKey) { // Ctrl+Ins + this._onInsertBefore(); + handled = true; + } else if (ctrlKey && shiftKey) { // Ctrl+Shift+Ins + this._onInsertAfter(); + handled = true; + } + } else if (keynum == 35) { // End + if (altKey) { // Alt+End + // find the last node + var lastNode = this._lastNode(); + if (lastNode) { + lastNode.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } + } else if (keynum == 36) { // Home + if (altKey) { // Alt+Home + // find the first node + var firstNode = this._firstNode(); + if (firstNode) { + firstNode.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } + } else if (keynum == 37) { // Arrow Left + if (altKey && !shiftKey) { // Alt + Arrow Left + // move to left element + var prevElement = this._previousElement(target); + if (prevElement) { + this.focus(this._getElementName(prevElement)); + } + handled = true; + } else if (altKey && shiftKey) { // Alt + Shift Arrow left + if (this.expanded) { + var appendDom = this.getAppend(); + nextDom = appendDom ? appendDom.nextSibling : undefined; + } else { + var dom = this.getDom(); + nextDom = dom.nextSibling; + } + if (nextDom) { + nextNode = Node.getNodeFromTarget(nextDom); + nextDom2 = nextDom.nextSibling; + nextNode2 = Node.getNodeFromTarget(nextDom2); + if (nextNode && nextNode instanceof AppendNode + && !(this.parent.childs.length == 1) && nextNode2 + && nextNode2.parent) { + nextNode2.parent.moveBefore(this, nextNode2); + this.focus(Node.focusElement + || this._getElementName(target)); + } + } + } + } else if (keynum == 38) { // Arrow Up + if (altKey && !shiftKey) { // Alt + Arrow Up + // find the previous node + prevNode = this._previousNode(); + if (prevNode) { + prevNode.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } else if (altKey && shiftKey) { // Alt + Shift + Arrow Up + // find the previous node + prevNode = this._previousNode(); + if (prevNode && prevNode.parent) { + prevNode.parent.moveBefore(this, prevNode); + this.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } + } else if (keynum == 39) { // Arrow Right + if (altKey && !shiftKey) { // Alt + Arrow Right + // move to right element + var nextElement = this._nextElement(target); + if (nextElement) { + this.focus(this._getElementName(nextElement)); + } + handled = true; + } else if (altKey && shiftKey) { // Alt + Shift Arrow Right + dom = this.getDom(); + var prevDom = dom.previousSibling; + if (prevDom) { + prevNode = Node.getNodeFromTarget(prevDom); + if (prevNode && prevNode.parent + && (prevNode instanceof AppendNode) + && !prevNode.isVisible()) { + prevNode.parent.moveBefore(this, prevNode); + this.focus(Node.focusElement + || this._getElementName(target)); + } + } + } + } else if (keynum == 40) { // Arrow Down + if (altKey && !shiftKey) { // Alt + Arrow Down + // find the next node + nextNode = this._nextNode(); + if (nextNode) { + nextNode.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } else if (altKey && shiftKey) { // Alt + Shift + Arrow Down + // find the 2nd next node and move before that one + if (this.expanded) { + nextNode = this.append ? this.append._nextNode() + : undefined; + } else { + nextNode = this._nextNode(); + } + nextDom = nextNode ? nextNode.getDom() : undefined; + if (this.parent.childs.length == 1) { + nextDom2 = nextDom; + } else { + nextDom2 = nextDom ? nextDom.nextSibling : undefined; + } + var nextNode2 = Node.getNodeFromTarget(nextDom2); + if (nextNode2 && nextNode2.parent) { + nextNode2.parent.moveBefore(this, nextNode2); + this.focus(Node.focusElement + || this._getElementName(target)); + } + handled = true; + } + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }; + + /** + * Handle the expand event, when clicked on the expand button + * + * @param {boolean} + * recurse If true, child nodes will be expanded too + * @private + */ + Node.prototype._onExpand = function(recurse) { + if (recurse) { + // Take the table offline + var table = this.dom.tr.parentNode; // TODO: not nice to access the + // main + // table like this + var frame = table.parentNode; + var scrollTop = frame.scrollTop; + frame.removeChild(table); + } + + if (this.expanded) { + this.collapse(recurse); + } else { + this.expand(recurse); + } + + if (recurse) { + // Put the table online again + frame.appendChild(table); + frame.scrollTop = scrollTop; + } + }; + + /** + * Remove this node + * + * @private + */ + Node.prototype._onRemove = function() { + this.editor.highlighter.unhighlight(); + var childs = this.parent.childs; + var index = childs.indexOf(this); + + // adjust the focus + var oldSelection = this.editor.getSelection(); + if (childs[index + 1]) { + childs[index + 1].focus(); + } else if (childs[index - 1]) { + childs[index - 1].focus(); + } else { + this.parent.focus(); + } + var newSelection = this.editor.getSelection(); + + // remove the node + this.parent._remove(this); + + // store history action + this.editor._onAction('removeNode', { + 'node' : this, + 'parent' : this.parent, + 'index' : index, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + }; + + /** + * Duplicate this node + * + * @private + */ + Node.prototype._onDuplicate = function() { + var oldSelection = this.editor.getSelection(); + var clone = this.parent._duplicate(this); + clone.focus(); + var newSelection = this.editor.getSelection(); + + this.editor._onAction('duplicateNode', { + 'node' : this, + 'clone' : clone, + 'parent' : this.parent, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + }; + + /** + * Handle insert before event + * + * @param {String} + * [field] + * @param {*} + * [value] + * @param {String} + * [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + Node.prototype._onInsertBefore = function(field, value, type) { + var oldSelection = this.editor.getSelection(); + + var newNode = new Node(this.editor, { + 'field' : (field != undefined) ? field : '', + 'value' : (value != undefined) ? value : '', + 'type' : type + }); + newNode.expand(true); + this.parent.insertBefore(newNode, this); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getSelection(); + + this.editor._onAction('insertBeforeNode', { + 'node' : newNode, + 'beforeNode' : this, + 'parent' : this.parent, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + }; + + /** + * Handle insert after event + * + * @param {String} + * [field] + * @param {*} + * [value] + * @param {String} + * [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + Node.prototype._onInsertAfter = function(field, value, type) { + var oldSelection = this.editor.getSelection(); + + var newNode = new Node(this.editor, { + 'field' : (field != undefined) ? field : '', + 'value' : (value != undefined) ? value : '', + 'type' : type + }); + newNode.expand(true); + this.parent.insertAfter(newNode, this); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getSelection(); + + this.editor._onAction('insertAfterNode', { + 'node' : newNode, + 'afterNode' : this, + 'parent' : this.parent, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + }; + + /** + * Handle append event + * + * @param {String} + * [field] + * @param {*} + * [value] + * @param {String} + * [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + Node.prototype._onAppend = function(field, value, type) { + var oldSelection = this.editor.getSelection(); + + var newNode = new Node(this.editor, { + 'field' : (field != undefined) ? field : '', + 'value' : (value != undefined) ? value : '', + 'type' : type + }); + newNode.expand(true); + this.parent.appendChild(newNode); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getSelection(); + + this.editor._onAction('appendNode', { + 'node' : newNode, + 'parent' : this.parent, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + }; + + /** + * Change the type of the node's value + * + * @param {String} + * newType + * @private + */ + Node.prototype._onChangeType = function(newType) { + var oldType = this.type; + if (newType != oldType) { + var oldSelection = this.editor.getSelection(); + this.changeType(newType); + var newSelection = this.editor.getSelection(); + + this.editor._onAction('changeType', { + 'node' : this, + 'oldType' : oldType, + 'newType' : newType, + 'oldSelection' : oldSelection, + 'newSelection' : newSelection + }); + } + }; + + /** + * Sort the childs of the node. Only applicable when the node has type + * 'object' or 'array'. + * + * @param {String} + * direction Sorting direction. Available values: "asc", "desc" + * @private + */ + Node.prototype._onSort = function(direction) { + if (this._hasChilds()) { + var order = (direction == 'desc') ? -1 : 1; + var prop = (this.type == 'array') ? 'value' : 'field'; + this.hideChilds(); + + var oldChilds = this.childs; + var oldSort = this.sort; + + // copy the array (the old one will be kept for an undo action + this.childs = this.childs.concat(); + + // sort the arrays + this.childs.sort(function(a, b) { + if (a[prop] > b[prop]) + return order; + if (a[prop] < b[prop]) + return -order; + return 0; + }); + this.sort = (order == 1) ? 'asc' : 'desc'; + + this.editor._onAction('sort', { + 'node' : this, + 'oldChilds' : oldChilds, + 'oldSort' : oldSort, + 'newChilds' : this.childs, + 'newSort' : this.sort + }); + + this.showChilds(); + } + }; + + /** + * Create a table row with an append button. + * + * @return {HTMLElement | undefined} buttonAppend or undefined when + * inapplicable + */ + Node.prototype.getAppend = function() { + if (!this.append) { + this.append = new AppendNode(this.editor); + this.append.setParent(this); + } + return this.append.getDom(); + }; + + /** + * Find the node from an event target + * + * @param {Node} + * target + * @return {Node | undefined} node or undefined when not found + * @static + */ + Node.getNodeFromTarget = function(target) { + while (target) { + if (target.node) { + return target.node; + } + target = target.parentNode; + } + + return undefined; + }; + + /** + * Get the previously rendered node + * + * @return {Node | null} previousNode + * @private + */ + Node.prototype._previousNode = function() { + var prevNode = null; + var dom = this.getDom(); + if (dom && dom.parentNode) { + // find the previous field + var prevDom = dom; + do { + prevDom = prevDom.previousSibling; + prevNode = Node.getNodeFromTarget(prevDom); + } while (prevDom + && (prevNode instanceof AppendNode && !prevNode.isVisible())); + } + return prevNode; + }; + + /** + * Get the next rendered node + * + * @return {Node | null} nextNode + * @private + */ + Node.prototype._nextNode = function() { + var nextNode = null; + var dom = this.getDom(); + if (dom && dom.parentNode) { + // find the previous field + var nextDom = dom; + do { + nextDom = nextDom.nextSibling; + nextNode = Node.getNodeFromTarget(nextDom); + } while (nextDom + && (nextNode instanceof AppendNode && !nextNode.isVisible())); + } + + return nextNode; + }; + + /** + * Get the first rendered node + * + * @return {Node | null} firstNode + * @private + */ + Node.prototype._firstNode = function() { + var firstNode = null; + var dom = this.getDom(); + if (dom && dom.parentNode) { + var firstDom = dom.parentNode.firstChild; + firstNode = Node.getNodeFromTarget(firstDom); + } + + return firstNode; + }; + + /** + * Get the last rendered node + * + * @return {Node | null} lastNode + * @private + */ + Node.prototype._lastNode = function() { + var lastNode = null; + var dom = this.getDom(); + if (dom && dom.parentNode) { + var lastDom = dom.parentNode.lastChild; + lastNode = Node.getNodeFromTarget(lastDom); + while (lastDom + && (lastNode instanceof AppendNode && !lastNode.isVisible())) { + lastDom = lastDom.previousSibling; + lastNode = Node.getNodeFromTarget(lastDom); + } + } + return lastNode; + }; + + /** + * Get the next element which can have focus. + * + * @param {Element} + * elem + * @return {Element | null} nextElem + * @private + */ + Node.prototype._previousElement = function(elem) { + var dom = this.dom; + // noinspection FallthroughInSwitchStatementJS + switch (elem) { + case dom.value: + if (this.fieldEditable) { + return dom.field; + } + // intentional fall through + case dom.field: + if (this._hasChilds()) { + return dom.expand; + } + // intentional fall through + case dom.expand: + return dom.menu; + case dom.menu: + if (dom.drag) { + return dom.drag; + } + // intentional fall through + default: + return null; + } + }; + + /** + * Get the next element which can have focus. + * + * @param {Element} + * elem + * @return {Element | null} nextElem + * @private + */ + Node.prototype._nextElement = function(elem) { + var dom = this.dom; + // noinspection FallthroughInSwitchStatementJS + switch (elem) { + case dom.drag: + return dom.menu; + case dom.menu: + if (this._hasChilds()) { + return dom.expand; + } + // intentional fall through + case dom.expand: + if (this.fieldEditable) { + return dom.field; + } + // intentional fall through + case dom.field: + if (!this._hasChilds()) { + return dom.value; + } + default: + return null; + } + }; + + /** + * Get the dom name of given element. returns null if not found. For example + * when element == dom.field, "field" is returned. + * + * @param {Element} + * element + * @return {String | null} elementName Available elements with name: 'drag', + * 'menu', 'expand', 'field', 'value' + * @private + */ + Node.prototype._getElementName = function(element) { + var dom = this.dom; + for ( var name in dom) { + if (dom.hasOwnProperty(name)) { + if (dom[name] == element) { + return name; + } + } + } + return null; + }; + + /** + * Test if this node has childs. This is the case when the node is an object + * or array. + * + * @return {boolean} hasChilds + * @private + */ + Node.prototype._hasChilds = function() { + return this.type == 'array' || this.type == 'object'; + }; + + // titles with explanation for the different types + Node.TYPE_TITLES = { + 'auto' : 'Field type "auto". ' + + 'The field type is automatically determined from the value ' + + 'and can be a string, number, boolean, or null.', + 'object' : 'Field type "object". ' + + 'An object contains an unordered set of key/value pairs.', + 'array' : 'Field type "array". ' + + 'An array contains an ordered collection of values.', + 'string' : 'Field type "string". ' + + 'Field type is not determined from the value, ' + + 'but always returned as string.' + }; + + /** + * Show a contextmenu for this node + * + * @param {HTMLElement} + * anchor Anchor element to attache the context menu to. + * @param {function} + * [onClose] Callback method called when the context menu is + * being closed. + */ + Node.prototype.showContextMenu = function(anchor, onClose) { + var node = this; + var titles = Node.TYPE_TITLES; + var items = []; + + items.push({ + 'text' : 'Type', + 'title' : 'Change the type of this field', + 'className' : 'type-' + this.type, + 'submenu' : [ + { + 'text' : 'Auto', + 'className' : 'type-auto' + + (this.type == 'auto' ? ' selected' : ''), + 'title' : titles.auto, + 'click' : function() { + node._onChangeType('auto'); + } + }, + { + 'text' : 'Array', + 'className' : 'type-array' + + (this.type == 'array' ? ' selected' : ''), + 'title' : titles.array, + 'click' : function() { + node._onChangeType('array'); + } + }, + { + 'text' : 'Object', + 'className' : 'type-object' + + (this.type == 'object' ? ' selected' : ''), + 'title' : titles.object, + 'click' : function() { + node._onChangeType('object'); + } + }, + { + 'text' : 'String', + 'className' : 'type-string' + + (this.type == 'string' ? ' selected' : ''), + 'title' : titles.string, + 'click' : function() { + node._onChangeType('string'); + } + } ] + }); + + if (this._hasChilds()) { + var direction = ((this.sort == 'asc') ? 'desc' : 'asc'); + items.push({ + 'text' : 'Sort', + 'title' : 'Sort the childs of this ' + this.type, + 'className' : 'sort-' + direction, + 'click' : function() { + node._onSort(direction); + }, + 'submenu' : [ + { + 'text' : 'Ascending', + 'className' : 'sort-asc', + 'title' : 'Sort the childs of this ' + this.type + + ' in ascending order', + 'click' : function() { + node._onSort('asc'); + } + }, + { + 'text' : 'Descending', + 'className' : 'sort-desc', + 'title' : 'Sort the childs of this ' + this.type + + ' in descending order', + 'click' : function() { + node._onSort('desc'); + } + } ] + }); + } + + if (this.parent && this.parent._hasChilds()) { + // create a separator + items.push({ + 'type' : 'separator' + }); + + // create append button (for last child node only) + var childs = node.parent.childs; + if (node == childs[childs.length - 1]) { + items + .push({ + 'text' : 'Append', + 'title' : 'Append a new field with type \'auto\' after this field (Ctrl+Shift+Ins)', + 'submenuTitle' : 'Select the type of the field to be appended', + 'className' : 'append', + 'click' : function() { + node._onAppend('', '', 'auto'); + }, + 'submenu' : [ { + 'text' : 'Auto', + 'className' : 'type-auto', + 'title' : titles.auto, + 'click' : function() { + node._onAppend('', '', 'auto'); + } + }, { + 'text' : 'Array', + 'className' : 'type-array', + 'title' : titles.array, + 'click' : function() { + node._onAppend('', []); + } + }, { + 'text' : 'Object', + 'className' : 'type-object', + 'title' : titles.object, + 'click' : function() { + node._onAppend('', {}); + } + }, { + 'text' : 'String', + 'className' : 'type-string', + 'title' : titles.string, + 'click' : function() { + node._onAppend('', '', 'string'); + } + } ] + }); + } + + // create insert button + items + .push({ + 'text' : 'Insert', + 'title' : 'Insert a new field with type \'auto\' before this field (Ctrl+Ins)', + 'submenuTitle' : 'Select the type of the field to be inserted', + 'className' : 'insert', + 'click' : function() { + node._onInsertBefore('', '', 'auto'); + }, + 'submenu' : [ { + 'text' : 'Auto', + 'className' : 'type-auto', + 'title' : titles.auto, + 'click' : function() { + node._onInsertBefore('', '', 'auto'); + } + }, { + 'text' : 'Array', + 'className' : 'type-array', + 'title' : titles.array, + 'click' : function() { + node._onInsertBefore('', []); + } + }, { + 'text' : 'Object', + 'className' : 'type-object', + 'title' : titles.object, + 'click' : function() { + node._onInsertBefore('', {}); + } + }, { + 'text' : 'String', + 'className' : 'type-string', + 'title' : titles.string, + 'click' : function() { + node._onInsertBefore('', '', 'string'); + } + } ] + }); + + // create duplicate button + items.push({ + 'text' : 'Duplicate', + 'title' : 'Duplicate this field (Ctrl+D)', + 'className' : 'duplicate', + 'click' : function() { + node._onDuplicate(); + } + }); + + // create remove button + items.push({ + 'text' : 'Remove', + 'title' : 'Remove this field (Ctrl+Del)', + 'className' : 'remove', + 'click' : function() { + node._onRemove(); + } + }); + } + + var menu = new ContextMenu(items, { + close : onClose + }); + menu.show(anchor); + }; + + /** + * get the type of a value + * + * @param {*} + * value + * @return {String} type Can be 'object', 'array', 'string', 'auto' + * @private + */ + Node.prototype._getType = function(value) { + if (value instanceof Array) { + return 'array'; + } + if (value instanceof Object) { + return 'object'; + } + if (typeof (value) == 'string' + && typeof (this._stringCast(value)) != 'string') { + return 'string'; + } + + return 'auto'; + }; + + /** + * cast contents of a string to the correct type. This can be a string, a + * number, a boolean, etc + * + * @param {String} + * str + * @return {*} castedStr + * @private + */ + Node.prototype._stringCast = function(str) { + var lower = str.toLowerCase(), num = Number(str), // will nicely fail + // with '123ab' + numFloat = parseFloat(str); // will nicely fail with ' ' + + if (str == '') { + return ''; + } else if (lower == 'null') { + return null; + } else if (lower == 'true') { + return true; + } else if (lower == 'false') { + return false; + } else if (!isNaN(num) && !isNaN(numFloat)) { + return num; + } else { + return str; + } + }; + + /** + * escape a text, such that it can be displayed safely in an HTML element + * + * @param {String} + * text + * @return {String} escapedText + * @private + */ + Node.prototype._escapeHTML = function(text) { + var htmlEscaped = String(text).replace(//g, + '>').replace(/ /g, '  ') // replace double space with + // an nbsp and + // space + .replace(/^ /, ' ') // space at start + .replace(/ $/, ' '); // space at end + + var json = JSON.stringify(htmlEscaped); + return json.substring(1, json.length - 1); + }; + + /** + * unescape a string. + * + * @param {String} + * escapedText + * @return {String} text + * @private + */ + Node.prototype._unescapeHTML = function(escapedText) { + var json = '"' + this._escapeJSON(escapedText) + '"'; + var htmlEscaped = util.parse(json); + return htmlEscaped.replace(/</g, '<').replace(/>/g, '>').replace( + / |\u00A0/g, ' '); + }; + + /** + * escape a text to make it a valid JSON string. The method will: - replace + * unescaped double quotes with '\"' - replace unescaped backslash with '\\' - + * replace returns with '\n' + * + * @param {String} + * text + * @return {String} escapedText + * @private + */ + Node.prototype._escapeJSON = function(text) { + // TODO: replace with some smart regex (only when a new solution is + // faster!) + var escaped = ''; + var i = 0, iMax = text.length; + while (i < iMax) { + var c = text.charAt(i); + if (c == '\n') { + escaped += '\\n'; + } else if (c == '\\') { + escaped += c; + i++; + + c = text.charAt(i); + if ('"\\/bfnrtu'.indexOf(c) == -1) { + escaped += '\\'; // no valid escape character + } + escaped += c; + } else if (c == '"') { + escaped += '\\"'; + } else { + escaped += c; + } + i++; + } + + return escaped; + }; + + /** + * @constructor AppendNode + * @extends Node + * @param {TreeEditor} + * editor Create a new AppendNode. This is a special node which + * is created at the end of the list with childs for an object or + * array + */ + function AppendNode(editor) { + /** @type {TreeEditor} */ + this.editor = editor; + this.dom = {}; + } + + AppendNode.prototype = new Node(); + + /** + * Return a table row with an append button. + * + * @return {Element} dom TR element + */ + AppendNode.prototype.getDom = function() { + // TODO: implement a new solution for the append node + var dom = this.dom; + + if (dom.tr) { + return dom.tr; + } + + // a row for the append button + var trAppend = document.createElement('tr'); + trAppend.node = this; + dom.tr = trAppend; + + // TODO: consistent naming + + if (this.editor.mode.edit) { + // a cell for the dragarea column + dom.tdDrag = document.createElement('td'); + + // create context menu + var tdMenu = document.createElement('td'); + dom.tdMenu = tdMenu; + var menu = document.createElement('button'); + menu.className = 'contextmenu'; + menu.title = 'Click to open the actions menu (Ctrl+M)'; + dom.menu = menu; + tdMenu.appendChild(dom.menu); + } + + // a cell for the contents (showing text 'empty') + var tdAppend = document.createElement('td'); + var domText = document.createElement('div'); + domText.innerHTML = '(empty)'; + domText.className = 'readonly'; + tdAppend.appendChild(domText); + dom.td = tdAppend; + dom.text = domText; + + this.updateDom(); + + return trAppend; + }; + + /** + * Update the HTML dom of the Node + */ + AppendNode.prototype.updateDom = function() { + var dom = this.dom; + var tdAppend = dom.td; + if (tdAppend) { + tdAppend.style.paddingLeft = (this.getLevel() * 24 + 26) + 'px'; + // TODO: not so nice hard coded offset + } + + var domText = dom.text; + if (domText) { + domText.innerHTML = '(empty ' + this.parent.type + ')'; + } + + // attach or detach the contents of the append node: + // hide when the parent has childs, show when the parent has no childs + var trAppend = dom.tr; + if (!this.isVisible()) { + if (dom.tr.firstChild) { + if (dom.tdDrag) { + trAppend.removeChild(dom.tdDrag); + } + if (dom.tdMenu) { + trAppend.removeChild(dom.tdMenu); + } + trAppend.removeChild(tdAppend); + } + } else { + if (!dom.tr.firstChild) { + if (dom.tdDrag) { + trAppend.appendChild(dom.tdDrag); + } + if (dom.tdMenu) { + trAppend.appendChild(dom.tdMenu); + } + trAppend.appendChild(tdAppend); + } + } + }; + + /** + * Check whether the AppendNode is currently visible. the AppendNode is + * visible when its parent has no childs (i.e. is empty). + * + * @return {boolean} isVisible + */ + AppendNode.prototype.isVisible = function() { + return (this.parent.childs.length == 0); + }; + + /** + * Show a contextmenu for this node + * + * @param {HTMLElement} + * anchor The element to attach the menu to. + * @param {function} + * [onClose] Callback method called when the context menu is + * being closed. + */ + AppendNode.prototype.showContextMenu = function(anchor, onClose) { + var node = this; + var titles = Node.TYPE_TITLES; + var items = [ + // create append button + { + 'text' : 'Append', + 'title' : 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)', + 'submenuTitle' : 'Select the type of the field to be appended', + 'className' : 'insert', + 'click' : function() { + node._onAppend('', '', 'auto'); + }, + 'submenu' : [ { + 'text' : 'Auto', + 'className' : 'type-auto', + 'title' : titles.auto, + 'click' : function() { + node._onAppend('', '', 'auto'); + } + }, { + 'text' : 'Array', + 'className' : 'type-array', + 'title' : titles.array, + 'click' : function() { + node._onAppend('', []); + } + }, { + 'text' : 'Object', + 'className' : 'type-object', + 'title' : titles.object, + 'click' : function() { + node._onAppend('', {}); + } + }, { + 'text' : 'String', + 'className' : 'type-string', + 'title' : titles.string, + 'click' : function() { + node._onAppend('', '', 'string'); + } + } ] + } ]; + + var menu = new ContextMenu(items, { + close : onClose + }); + menu.show(anchor); + }; + + /** + * Handle an event. The event is catched centrally by the editor + * + * @param {Event} + * event + */ + AppendNode.prototype.onEvent = function(event) { + var type = event.type; + var target = event.target || event.srcElement; + var dom = this.dom; + + // highlight the append nodes parent + var menu = dom.menu; + if (target == menu) { + if (type == 'mouseover') { + this.editor.highlighter.highlight(this.parent); + } else if (type == 'mouseout') { + this.editor.highlighter.unhighlight(); + } + } + + // context menu events + if (type == 'click' && target == dom.menu) { + var highlighter = this.editor.highlighter; + highlighter.highlight(this.parent); + highlighter.lock(); + util.addClassName(dom.menu, 'selected'); + this.showContextMenu(dom.menu, function() { + util.removeClassName(dom.menu, 'selected'); + highlighter.unlock(); + highlighter.unhighlight(); + }); + } + + if (type == 'keydown') { + this.onKeyDown(event); + } + }; + + /** + * A context menu + * + * @param {Object[]} + * items Array containing the menu structure TODO: describe + * structure + * @param {Object} + * [options] Object with options. Available options: {function} + * close Callback called when the context menu is being closed. + * @constructor + */ + function ContextMenu(items, options) { + this.dom = {}; + + var me = this; + var dom = this.dom; + this.anchor = undefined; + this.items = items; + this.eventListeners = {}; + this.selection = undefined; // holds the selection before the menu was + // opened + this.visibleSubmenu = undefined; + this.onClose = options ? options.close : undefined; + + // create a container element + var menu = document.createElement('div'); + menu.className = 'jsoneditor-contextmenu'; + dom.menu = menu; + + // create a list to hold the menu items + var list = document.createElement('ul'); + list.className = 'menu'; + menu.appendChild(list); + dom.list = list; + dom.items = []; // list with all buttons + + // create a (non-visible) button to set the focus to the menu + var focusButton = document.createElement('button'); + dom.focusButton = focusButton; + var li = document.createElement('li'); + li.style.overflow = 'hidden'; + li.style.height = '0'; + li.appendChild(focusButton); + list.appendChild(li); + + function createMenuItems(list, domItems, items) { + items + .forEach(function(item) { + if (item.type == 'separator') { + // create a separator + var separator = document.createElement('div'); + separator.className = 'separator'; + li = document.createElement('li'); + li.appendChild(separator); + list.appendChild(li); + } else { + var domItem = {}; + + // create a menu item + var li = document.createElement('li'); + list.appendChild(li); + + // create a button in the menu item + var button = document.createElement('button'); + button.className = item.className; + domItem.button = button; + if (item.title) { + button.title = item.title; + } + if (item.click) { + button.onclick = function() { + me.hide(); + item.click(); + }; + } + li.appendChild(button); + + // create the contents of the button + if (item.submenu) { + // add the icon to the button + var divIcon = document.createElement('div'); + divIcon.className = 'icon'; + button.appendChild(divIcon); + button.appendChild(document + .createTextNode(item.text)); + + var buttonSubmenu; + if (item.click) { + // submenu and a button with a click handler + button.className += ' default'; + + var buttonExpand = document + .createElement('button'); + domItem.buttonExpand = buttonExpand; + buttonExpand.className = 'expand'; + buttonExpand.innerHTML = '

'; + li.appendChild(buttonExpand); + if (item.submenuTitle) { + buttonExpand.title = item.submenuTitle; + } + + buttonSubmenu = buttonExpand; + } else { + // submenu and a button without a click + // handler + var divExpand = document + .createElement('div'); + divExpand.className = 'expand'; + button.appendChild(divExpand); + + buttonSubmenu = button; + } + + // attach a handler to expand/collapse the + // submenu + buttonSubmenu.onclick = function() { + me._onExpandItem(domItem); + buttonSubmenu.focus(); + }; + + // create the submenu + var domSubItems = []; + domItem.subItems = domSubItems; + var ul = document.createElement('ul'); + domItem.ul = ul; + ul.className = 'menu'; + ul.style.height = '0'; + li.appendChild(ul); + createMenuItems(ul, domSubItems, item.submenu); + } else { + // no submenu, just a button with clickhandler + button.innerHTML = '
' + + item.text; + } + + domItems.push(domItem); + } + }); + } + createMenuItems(list, this.dom.items, items); + + // TODO: when the editor is small, show the submenu on the right instead + // of + // inline? + + // calculate the max height of the menu with one submenu expanded + this.maxHeight = 0; // height in pixels + items.forEach(function(item) { + var height = (items.length + (item.submenu ? item.submenu.length + : 0)) * 24; + me.maxHeight = Math.max(me.maxHeight, height); + }); + } + + /** + * Get the currently visible buttons + * + * @return {Array.} buttons + * @private + */ + ContextMenu.prototype._getVisibleButtons = function() { + var buttons = []; + var me = this; + this.dom.items.forEach(function(item) { + buttons.push(item.button); + if (item.buttonExpand) { + buttons.push(item.buttonExpand); + } + if (item.subItems && item == me.expandedItem) { + item.subItems.forEach(function(subItem) { + buttons.push(subItem.button); + if (subItem.buttonExpand) { + buttons.push(subItem.buttonExpand); + } + // TODO: change to fully recursive method + }); + } + }); + + return buttons; + }; + + // currently displayed context menu, a singleton. We may only have one + // visible + // context menu + ContextMenu.visibleMenu = undefined; + + /** + * Attach the menu to an anchor + * + * @param {HTMLElement} + * anchor + */ + ContextMenu.prototype.show = function(anchor) { + this.hide(); + + // calculate whether the menu fits below the anchor + var windowHeight = window.innerHeight, windowScroll = (window.pageYOffset || document.scrollTop), windowBottom = windowHeight + + windowScroll, anchorHeight = anchor.offsetHeight, menuHeight = this.maxHeight; + + // position the menu + var left = util.getAbsoluteLeft(anchor); + var top = util.getAbsoluteTop(anchor); + if (top + anchorHeight + menuHeight < windowBottom) { + // display the menu below the anchor + this.dom.menu.style.left = left + 'px'; + this.dom.menu.style.top = (top + anchorHeight) + 'px'; + this.dom.menu.style.bottom = ''; + } else { + // display the menu above the anchor + this.dom.menu.style.left = left + 'px'; + this.dom.menu.style.top = ''; + this.dom.menu.style.bottom = (windowHeight - top) + 'px'; + } + + // attach the menu to the document + document.body.appendChild(this.dom.menu); + + // create and attach event listeners + var me = this; + var list = this.dom.list; + this.eventListeners.mousedown = util.addEventListener(document, + 'mousedown', function(event) { + // hide menu on click outside of the menu + var target = event.target; + if ((target != list) && !me._isChildOf(target, list)) { + me.hide(); + event.stopPropagation(); + event.preventDefault(); + } + }); + this.eventListeners.mousewheel = util.addEventListener(document, + 'mousewheel', function(event) { + // block scrolling when context menu is visible + event.stopPropagation(); + event.preventDefault(); + }); + this.eventListeners.keydown = util.addEventListener(document, + 'keydown', function(event) { + me._onKeyDown(event); + }); + + // move focus to the first button in the context menu + this.selection = util.getSelection(); + this.anchor = anchor; + setTimeout(function() { + me.dom.focusButton.focus(); + }, 0); + + if (ContextMenu.visibleMenu) { + ContextMenu.visibleMenu.hide(); + } + ContextMenu.visibleMenu = this; + }; + + /** + * Hide the context menu if visible + */ + ContextMenu.prototype.hide = function() { + // remove the menu from the DOM + if (this.dom.menu.parentNode) { + this.dom.menu.parentNode.removeChild(this.dom.menu); + if (this.onClose) { + this.onClose(); + } + } + + // remove all event listeners + // all event listeners are supposed to be attached to document. + for ( var name in this.eventListeners) { + if (this.eventListeners.hasOwnProperty(name)) { + var fn = this.eventListeners[name]; + if (fn) { + util.removeEventListener(document, name, fn); + } + delete this.eventListeners[name]; + } + } + + if (ContextMenu.visibleMenu == this) { + ContextMenu.visibleMenu = undefined; + } + }; + + /** + * Expand a submenu Any currently expanded submenu will be hided. + * + * @param {Object} + * domItem + * @private + */ + ContextMenu.prototype._onExpandItem = function(domItem) { + var me = this; + var alreadyVisible = (domItem == this.expandedItem); + + // hide the currently visible submenu + var expandedItem = this.expandedItem; + if (expandedItem) { + // var ul = expandedItem.ul; + expandedItem.ul.style.height = '0'; + expandedItem.ul.style.padding = ''; + setTimeout(function() { + if (me.expandedItem != expandedItem) { + expandedItem.ul.style.display = ''; + util + .removeClassName(expandedItem.ul.parentNode, + 'selected'); + } + }, 300); // timeout duration must match the css transition + // duration + this.expandedItem = undefined; + } + + if (!alreadyVisible) { + var ul = domItem.ul; + ul.style.display = 'block'; + var height = ul.clientHeight; // force a reflow in Firefox + setTimeout(function() { + if (me.expandedItem == domItem) { + ul.style.height = (ul.childNodes.length * 24) + 'px'; + ul.style.padding = '5px 10px'; + } + }, 0); + util.addClassName(ul.parentNode, 'selected'); + this.expandedItem = domItem; + } + }; + + /** + * Handle onkeydown event + * + * @param {Event} + * event + * @private + */ + ContextMenu.prototype._onKeyDown = function(event) { + var target = event.target; + var keynum = event.which; + var handled = false; + var buttons, targetIndex, prevButton, nextButton; + + if (keynum == 27) { // ESC + // hide the menu on ESC key + + // restore previous selection and focus + if (this.selection) { + util.setSelection(this.selection); + } + if (this.anchor) { + this.anchor.focus(); + } + + this.hide(); + + handled = true; + } else if (keynum == 9) { // Tab + if (!event.shiftKey) { // Tab + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + if (targetIndex == buttons.length - 1) { + // move to first button + buttons[0].focus(); + handled = true; + } + } else { // Shift+Tab + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + if (targetIndex == 0) { + // move to last button + buttons[buttons.length - 1].focus(); + handled = true; + } + } + } else if (keynum == 37) { // Arrow Left + if (target.className == 'expand') { + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + prevButton = buttons[targetIndex - 1]; + if (prevButton) { + prevButton.focus(); + } + } + handled = true; + } else if (keynum == 38) { // Arrow Up + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + prevButton = buttons[targetIndex - 1]; + if (prevButton && prevButton.className == 'expand') { + // skip expand button + prevButton = buttons[targetIndex - 2]; + } + if (!prevButton) { + // move to last button + prevButton = buttons[buttons.length - 1]; + } + if (prevButton) { + prevButton.focus(); + } + handled = true; + } else if (keynum == 39) { // Arrow Right + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + nextButton = buttons[targetIndex + 1]; + if (nextButton && nextButton.className == 'expand') { + nextButton.focus(); + } + handled = true; + } else if (keynum == 40) { // Arrow Down + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + nextButton = buttons[targetIndex + 1]; + if (nextButton && nextButton.className == 'expand') { + // skip expand button + nextButton = buttons[targetIndex + 2]; + } + if (!nextButton) { + // move to first button + nextButton = buttons[0]; + } + if (nextButton) { + nextButton.focus(); + handled = true; + } + handled = true; + } + // TODO: arrow left and right + + if (handled) { + event.stopPropagation(); + event.preventDefault(); + } + }; + + /** + * Test if an element is a child of a parent element. + * + * @param {Element} + * child + * @param {Element} + * parent + * @return {boolean} isChild + */ + ContextMenu.prototype._isChildOf = function(child, parent) { + var e = child.parentNode; + while (e) { + if (e == parent) { + return true; + } + e = e.parentNode; + } + + return false; + }; + + /** + * @constructor History Store action history, enables undo and redo + * @param {JSONEditor} + * editor + */ + function History(editor) { + this.editor = editor; + this.clear(); + + // map with all supported actions + this.actions = { + 'editField' : { + 'undo' : function(params) { + params.node.updateField(params.oldValue); + }, + 'redo' : function(params) { + params.node.updateField(params.newValue); + } + }, + 'editValue' : { + 'undo' : function(params) { + params.node.updateValue(params.oldValue); + }, + 'redo' : function(params) { + params.node.updateValue(params.newValue); + } + }, + 'appendNode' : { + 'undo' : function(params) { + params.parent.removeChild(params.node); + }, + 'redo' : function(params) { + params.parent.appendChild(params.node); + } + }, + 'insertBeforeNode' : { + 'undo' : function(params) { + params.parent.removeChild(params.node); + }, + 'redo' : function(params) { + params.parent.insertBefore(params.node, params.beforeNode); + } + }, + 'insertAfterNode' : { + 'undo' : function(params) { + params.parent.removeChild(params.node); + }, + 'redo' : function(params) { + params.parent.insertAfter(params.node, params.afterNode); + } + }, + 'removeNode' : { + 'undo' : function(params) { + var parent = params.parent; + var beforeNode = parent.childs[params.index] + || parent.append; + parent.insertBefore(params.node, beforeNode); + }, + 'redo' : function(params) { + params.parent.removeChild(params.node); + } + }, + 'duplicateNode' : { + 'undo' : function(params) { + params.parent.removeChild(params.clone); + }, + 'redo' : function(params) { + params.parent.insertAfter(params.clone, params.node); + } + }, + 'changeType' : { + 'undo' : function(params) { + params.node.changeType(params.oldType); + }, + 'redo' : function(params) { + params.node.changeType(params.newType); + } + }, + 'moveNode' : { + 'undo' : function(params) { + params.startParent.moveTo(params.node, params.startIndex); + }, + 'redo' : function(params) { + params.endParent.moveTo(params.node, params.endIndex); + } + }, + 'sort' : { + 'undo' : function(params) { + var node = params.node; + node.hideChilds(); + node.sort = params.oldSort; + node.childs = params.oldChilds; + node.showChilds(); + }, + 'redo' : function(params) { + var node = params.node; + node.hideChilds(); + node.sort = params.newSort; + node.childs = params.newChilds; + node.showChilds(); + } + } + + // TODO: restore the original caret position and selection with each + // undo + // TODO: implement history for actions "expand", "collapse", "scroll", + // "setDocument" + }; + } + + /** + * The method onChange is executed when the History is changed, and can be + * overloaded. + */ + History.prototype.onChange = function() { + }; + + /** + * Add a new action to the history + * + * @param {String} + * action The executed action. Available actions: "editField", + * "editValue", "changeType", "appendNode", "removeNode", + * "duplicateNode", "moveNode" + * @param {Object} + * params Object containing parameters describing the change. The + * parameters in params depend on the action (for example for + * "editValue" the Node, old value, and new value are provided). + * params contains all information needed to undo or redo the + * action. + */ + History.prototype.add = function(action, params) { + this.index++; + this.history[this.index] = { + 'action' : action, + 'params' : params, + 'timestamp' : new Date() + }; + + // remove redo actions which are invalid now + if (this.index < this.history.length - 1) { + this.history.splice(this.index + 1, this.history.length + - this.index - 1); + } + + // fire onchange event + this.onChange(); + }; + + /** + * Clear history + */ + History.prototype.clear = function() { + this.history = []; + this.index = -1; + + // fire onchange event + this.onChange(); + }; + + /** + * Check if there is an action available for undo + * + * @return {Boolean} canUndo + */ + History.prototype.canUndo = function() { + return (this.index >= 0); + }; + + /** + * Check if there is an action available for redo + * + * @return {Boolean} canRedo + */ + History.prototype.canRedo = function() { + return (this.index < this.history.length - 1); + }; + + /** + * Undo the last action + */ + History.prototype.undo = function() { + if (this.canUndo()) { + var obj = this.history[this.index]; + if (obj) { + var action = this.actions[obj.action]; + if (action && action.undo) { + action.undo(obj.params); + if (obj.params.oldSelection) { + this.editor.setSelection(obj.params.oldSelection); + } + } else { + util.log('Error: unknown action "' + obj.action + '"'); + } + } + this.index--; + + // fire onchange event + this.onChange(); + } + }; + + /** + * Redo the last action + */ + History.prototype.redo = function() { + if (this.canRedo()) { + this.index++; + + var obj = this.history[this.index]; + if (obj) { + var action = this.actions[obj.action]; + if (action && action.redo) { + action.redo(obj.params); + if (obj.params.newSelection) { + this.editor.setSelection(obj.params.newSelection); + } + } else { + util.log('Error: unknown action "' + obj.action + '"'); + } + } + + // fire onchange event + this.onChange(); + } + }; + + /** + * create a mode box to be used in the editor menu's + * + * @param {JSONEditor} + * editor + * @param {String[]} + * modes Available modes: 'code', 'form', 'text', 'tree', 'view' + * @param {String} + * current Available modes: 'code', 'form', 'text', 'tree', + * 'view' + * @returns {HTMLElement} box + */ + function createModeBox(editor, modes, current) { + /** + * Switch the mode of the editor + * + * @param {String} + * mode + */ + function switchMode(mode) { + // switch mode + editor.setMode(mode); + + // restore focus on mode box + var modeBox = editor.dom && editor.dom.modeBox; + if (modeBox) { + modeBox.focus(); + } + } + + // available modes + var availableModes = { + code : { + 'text' : 'Code', + 'title' : 'Switch to code highlighter', + 'click' : function() { + switchMode('code') + } + }, + form : { + 'text' : 'Form', + 'title' : 'Switch to form editor', + 'click' : function() { + switchMode('form'); + } + }, + text : { + 'text' : 'Text', + 'title' : 'Switch to plain text editor', + 'click' : function() { + switchMode('text'); + } + }, + tree : { + 'text' : 'Tree', + 'title' : 'Switch to tree editor', + 'click' : function() { + switchMode('tree'); + } + }, + view : { + 'text' : 'View', + 'title' : 'Switch to tree view', + 'click' : function() { + switchMode('view'); + } + } + }; + + // list the selected modes + var items = []; + for ( var i = 0; i < modes.length; i++) { + var mode = modes[i]; + var item = availableModes[mode]; + if (!item) { + throw new Error('Unknown mode "' + mode + '"'); + } + + item.className = 'type-modes' + + ((current == mode) ? ' selected' : ''); + items.push(item); + } + + // retrieve the title of current mode + var currentMode = availableModes[current]; + if (!currentMode) { + throw new Error('Unknown mode "' + current + '"'); + } + var currentTitle = currentMode.text; + + // create the html element + var box = document.createElement('button'); + box.className = 'modes separator'; + box.innerHTML = currentTitle + ' ▾'; + box.title = 'Switch editor mode'; + box.onclick = function() { + var menu = new ContextMenu(items); + menu.show(box); + }; + + return box; + } + + /** + * @constructor SearchBox Create a search box in given HTML container + * @param {JSONEditor} + * editor The JSON Editor to attach to + * @param {Element} + * container HTML container element of where to create the search + * box + */ + function SearchBox(editor, container) { + var searchBox = this; + + this.editor = editor; + this.timeout = undefined; + this.delay = 200; // ms + this.lastText = undefined; + + this.dom = {}; + this.dom.container = container; + + var table = document.createElement('table'); + this.dom.table = table; + table.className = 'search'; + container.appendChild(table); + var tbody = document.createElement('tbody'); + this.dom.tbody = tbody; + table.appendChild(tbody); + var tr = document.createElement('tr'); + tbody.appendChild(tr); + + var td = document.createElement('td'); + tr.appendChild(td); + var results = document.createElement('div'); + this.dom.results = results; + results.className = 'results'; + td.appendChild(results); + + td = document.createElement('td'); + tr.appendChild(td); + var divInput = document.createElement('div'); + this.dom.input = divInput; + divInput.className = 'frame'; + divInput.title = 'Search fields and values'; + td.appendChild(divInput); + + // table to contain the text input and search button + var tableInput = document.createElement('table'); + divInput.appendChild(tableInput); + var tbodySearch = document.createElement('tbody'); + tableInput.appendChild(tbodySearch); + tr = document.createElement('tr'); + tbodySearch.appendChild(tr); + + var refreshSearch = document.createElement('button'); + refreshSearch.className = 'refresh'; + td = document.createElement('td'); + td.appendChild(refreshSearch); + tr.appendChild(td); + + var search = document.createElement('input'); + this.dom.search = search; + search.oninput = function(event) { + searchBox._onDelayedSearch(event); + }; + search.onchange = function(event) { // For IE 9 + searchBox._onSearch(event); + }; + search.onkeydown = function(event) { + searchBox._onKeyDown(event); + }; + search.onkeyup = function(event) { + searchBox._onKeyUp(event); + }; + refreshSearch.onclick = function(event) { + search.select(); + }; + + // TODO: ESC in FF restores the last input, is a FF bug, + // https://bugzilla.mozilla.org/show_bug.cgi?id=598819 + td = document.createElement('td'); + td.appendChild(search); + tr.appendChild(td); + + var searchNext = document.createElement('button'); + searchNext.title = 'Next result (Enter)'; + searchNext.className = 'next'; + searchNext.onclick = function() { + searchBox.next(); + }; + td = document.createElement('td'); + td.appendChild(searchNext); + tr.appendChild(td); + + var searchPrevious = document.createElement('button'); + searchPrevious.title = 'Previous result (Shift+Enter)'; + searchPrevious.className = 'previous'; + searchPrevious.onclick = function() { + searchBox.previous(); + }; + td = document.createElement('td'); + td.appendChild(searchPrevious); + tr.appendChild(td); + } + + /** + * Go to the next search result + * + * @param {boolean} + * [focus] If true, focus will be set to the next result focus is + * false by default. + */ + SearchBox.prototype.next = function(focus) { + if (this.results != undefined) { + var index = (this.resultIndex != undefined) ? this.resultIndex + 1 + : 0; + if (index > this.results.length - 1) { + index = 0; + } + this._setActiveResult(index, focus); + } + }; + + /** + * Go to the prevous search result + * + * @param {boolean} + * [focus] If true, focus will be set to the next result focus is + * false by default. + */ + SearchBox.prototype.previous = function(focus) { + if (this.results != undefined) { + var max = this.results.length - 1; + var index = (this.resultIndex != undefined) ? this.resultIndex - 1 + : max; + if (index < 0) { + index = max; + } + this._setActiveResult(index, focus); + } + }; + + /** + * Set new value for the current active result + * + * @param {Number} + * index + * @param {boolean} + * [focus] If true, focus will be set to the next result. focus + * is false by default. + * @private + */ + SearchBox.prototype._setActiveResult = function(index, focus) { + // de-activate current active result + if (this.activeResult) { + var prevNode = this.activeResult.node; + var prevElem = this.activeResult.elem; + if (prevElem == 'field') { + delete prevNode.searchFieldActive; + } else { + delete prevNode.searchValueActive; + } + prevNode.updateDom(); + } + + if (!this.results || !this.results[index]) { + // out of range, set to undefined + this.resultIndex = undefined; + this.activeResult = undefined; + return; + } + + this.resultIndex = index; + + // set new node active + var node = this.results[this.resultIndex].node; + var elem = this.results[this.resultIndex].elem; + if (elem == 'field') { + node.searchFieldActive = true; + } else { + node.searchValueActive = true; + } + this.activeResult = this.results[this.resultIndex]; + node.updateDom(); + + // TODO: not so nice that the focus is only set after the animation is + // finished + node.scrollTo(function() { + if (focus) { + node.focus(elem); + } + }); + }; + + /** + * Cancel any running onDelayedSearch. + * + * @private + */ + SearchBox.prototype._clearDelay = function() { + if (this.timeout != undefined) { + clearTimeout(this.timeout); + delete this.timeout; + } + }; + + /** + * Start a timer to execute a search after a short delay. Used for reducing + * the number of searches while typing. + * + * @param {Event} + * event + * @private + */ + SearchBox.prototype._onDelayedSearch = function(event) { + // execute the search after a short delay (reduces the number of + // search actions while typing in the search text box) + this._clearDelay(); + var searchBox = this; + this.timeout = setTimeout(function(event) { + searchBox._onSearch(event); + }, this.delay); + }; + + /** + * Handle onSearch event + * + * @param {Event} + * event + * @param {boolean} + * [forceSearch] If true, search will be executed again even when + * the search text is not changed. Default is false. + * @private + */ + SearchBox.prototype._onSearch = function(event, forceSearch) { + this._clearDelay(); + + var value = this.dom.search.value; + var text = (value.length > 0) ? value : undefined; + if (text != this.lastText || forceSearch) { + // only search again when changed + this.lastText = text; + this.results = this.editor.search(text); + this._setActiveResult(undefined); + + // display search results + if (text != undefined) { + var resultCount = this.results.length; + switch (resultCount) { + case 0: + this.dom.results.innerHTML = 'no results'; + break; + case 1: + this.dom.results.innerHTML = '1 result'; + break; + default: + this.dom.results.innerHTML = resultCount + ' results'; + break; + } + } else { + this.dom.results.innerHTML = ''; + } + } + }; + + /** + * Handle onKeyDown event in the input box + * + * @param {Event} + * event + * @private + */ + SearchBox.prototype._onKeyDown = function(event) { + var keynum = event.which; + if (keynum == 27) { // ESC + this.dom.search.value = ''; // clear search + this._onSearch(event); + event.preventDefault(); + event.stopPropagation(); + } else if (keynum == 13) { // Enter + if (event.ctrlKey) { + // force to search again + this._onSearch(event, true); + } else if (event.shiftKey) { + // move to the previous search result + this.previous(); + } else { + // move to the next search result + this.next(); + } + event.preventDefault(); + event.stopPropagation(); + } + }; + + /** + * Handle onKeyUp event in the input box + * + * @param {Event} + * event + * @private + */ + SearchBox.prototype._onKeyUp = function(event) { + var keynum = event.keyCode; + if (keynum != 27 && keynum != 13) { // !show and !Enter + this._onDelayedSearch(event); // For IE 9 + } + }; + + /** + * The highlighter can highlight/unhighlight a node, and animate the + * visibility of a context menu. + * + * @constructor Highlighter + */ + function Highlighter() { + this.locked = false; + } + + /** + * Hightlight given node and its childs + * + * @param {Node} + * node + */ + Highlighter.prototype.highlight = function(node) { + if (this.locked) { + return; + } + + if (this.node != node) { + // unhighlight current node + if (this.node) { + this.node.setHighlight(false); + } + + // highlight new node + this.node = node; + this.node.setHighlight(true); + } + + // cancel any current timeout + this._cancelUnhighlight(); + }; + + /** + * Unhighlight currently highlighted node. Will be done after a delay + */ + Highlighter.prototype.unhighlight = function() { + if (this.locked) { + return; + } + + var me = this; + if (this.node) { + this._cancelUnhighlight(); + + // do the unhighlighting after a small delay, to prevent + // re-highlighting + // the same node when moving from the drag-icon to the + // contextmenu-icon + // or vice versa. + this.unhighlightTimer = setTimeout(function() { + me.node.setHighlight(false); + me.node = undefined; + me.unhighlightTimer = undefined; + }, 0); + } + }; + + /** + * Cancel an unhighlight action (if before the timeout of the unhighlight + * action) + * + * @private + */ + Highlighter.prototype._cancelUnhighlight = function() { + if (this.unhighlightTimer) { + clearTimeout(this.unhighlightTimer); + this.unhighlightTimer = undefined; + } + }; + + /** + * Lock highlighting or unhighlighting nodes. methods highlight and + * unhighlight do not work while locked. + */ + Highlighter.prototype.lock = function() { + this.locked = true; + }; + + /** + * Unlock highlighting or unhighlighting nodes + */ + Highlighter.prototype.unlock = function() { + this.locked = false; + }; + + // create namespace + util = {}; + + /** + * Parse JSON using the parser built-in in the browser. On exception, the + * jsonString is validated and a detailed error is thrown. + * + * @param {String} + * jsonString + */ + util.parse = function parse(jsonString) { + try { + return JSON.parse(jsonString); + } catch (err) { + // try to throw a more detailed error message using validate + util.validate(jsonString); + throw err; + } + }; + + /** + * Validate a string containing a JSON object This method uses JSONLint to + * validate the String. If JSONLint is not available, the built-in JSON + * parser of the browser is used. + * + * @param {String} + * jsonString String with an (invalid) JSON object + * @throws Error + */ + util.validate = function validate(jsonString) { + if (typeof (jsonlint) != 'undefined') { + jsonlint.parse(jsonString); + } else { + JSON.parse(jsonString); + } + }; + + /** + * Extend object a with the properties of object b + * + * @param {Object} + * a + * @param {Object} + * b + * @return {Object} a + */ + util.extend = function extend(a, b) { + for ( var prop in b) { + if (b.hasOwnProperty(prop)) { + a[prop] = b[prop]; + } + } + return a; + }; + + /** + * Remove all properties from object a + * + * @param {Object} + * a + * @return {Object} a + */ + util.clear = function clear(a) { + for ( var prop in a) { + if (a.hasOwnProperty(prop)) { + delete a[prop]; + } + } + return a; + }; + + /** + * Output text to the console, if console is available + * + * @param {...*} + * args + */ + util.log = function log(args) { + if (typeof console !== 'undefined' && typeof console.log === 'function') { + console.log.apply(console, arguments); + } + }; + + /** + * Get the type of an object + * + * @param {*} + * object + * @return {String} type + */ + util.type = function type(object) { + if (object === null) { + return 'null'; + } + if (object === undefined) { + return 'undefined'; + } + if ((object instanceof Number) || (typeof object === 'number')) { + return 'number'; + } + if ((object instanceof String) || (typeof object === 'string')) { + return 'string'; + } + if ((object instanceof Boolean) || (typeof object === 'boolean')) { + return 'boolean'; + } + if ((object instanceof RegExp) || (typeof object === 'regexp')) { + return 'regexp'; + } + if (Array.isArray(object)) { + return 'array'; + } + + return 'object'; + }; + + /** + * Test whether a text contains a url (matches when a string starts with + * 'http://*' or 'https://*' and has no whitespace characters) + * + * @param {String} + * text + */ + var isUrlRegex = /^https?:\/\/\S+$/; + util.isUrl = function isUrl(text) { + return (typeof text == 'string' || text instanceof String) + && isUrlRegex.test(text); + }; + + /** + * Retrieve the absolute left value of a DOM element + * + * @param {Element} + * elem A dom element, for example a div + * @return {Number} left The absolute left position of this element in the + * browser page. + */ + util.getAbsoluteLeft = function getAbsoluteLeft(elem) { + var rect = elem.getBoundingClientRect(); + return rect.left + window.pageXOffset || document.scrollLeft || 0; + }; + + /** + * Retrieve the absolute top value of a DOM element + * + * @param {Element} + * elem A dom element, for example a div + * @return {Number} top The absolute top position of this element in the + * browser page. + */ + util.getAbsoluteTop = function getAbsoluteTop(elem) { + var rect = elem.getBoundingClientRect(); + return rect.top + window.pageYOffset || document.scrollTop || 0; + }; + + /** + * add a className to the given elements style + * + * @param {Element} + * elem + * @param {String} + * className + */ + util.addClassName = function addClassName(elem, className) { + var classes = elem.className.split(' '); + if (classes.indexOf(className) == -1) { + classes.push(className); // add the class to the array + elem.className = classes.join(' '); + } + }; + + /** + * add a className to the given elements style + * + * @param {Element} + * elem + * @param {String} + * className + */ + util.removeClassName = function removeClassName(elem, className) { + var classes = elem.className.split(' '); + var index = classes.indexOf(className); + if (index != -1) { + classes.splice(index, 1); // remove the class from the array + elem.className = classes.join(' '); + } + }; + + /** + * Strip the formatting from the contents of a div the formatting from the + * div itself is not stripped, only from its childs. + * + * @param {Element} + * divElement + */ + util.stripFormatting = function stripFormatting(divElement) { + var childs = divElement.childNodes; + for ( var i = 0, iMax = childs.length; i < iMax; i++) { + var child = childs[i]; + + // remove the style + if (child.style) { + // TODO: test if child.attributes does contain style + child.removeAttribute('style'); + } + + // remove all attributes + var attributes = child.attributes; + if (attributes) { + for ( var j = attributes.length - 1; j >= 0; j--) { + var attribute = attributes[j]; + if (attribute.specified == true) { + child.removeAttribute(attribute.name); + } + } + } + + // recursively strip childs + util.stripFormatting(child); + } + }; + + /** + * Set focus to the end of an editable div code from Nico Burns + * http://stackoverflow.com/users/140293/nico-burns + * http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity + * + * @param {Element} + * contentEditableElement A content editable div + */ + util.setEndOfContentEditable = function setEndOfContentEditable( + contentEditableElement) { + var range, selection; + if (document.createRange) { + range = document.createRange();// Create a range (a range is a like + // the + // selection but invisible) + range.selectNodeContents(contentEditableElement);// Select the + // entire + // contents of the + // element with the + // range + range.collapse(false);// collapse the range to the end point. + // false means + // collapse to end rather than the start + selection = window.getSelection();// get the selection object + // (allows you + // to change selection) + selection.removeAllRanges();// remove any selections already made + selection.addRange(range);// make the range you have just created + // the + // visible selection + } + }; + + /** + * Select all text of a content editable div. + * http://stackoverflow.com/a/3806004/1262753 + * + * @param {Element} + * contentEditableElement A content editable div + */ + util.selectContentEditable = function selectContentEditable( + contentEditableElement) { + if (!contentEditableElement || contentEditableElement.nodeName != 'DIV') { + return; + } + + var sel, range; + if (window.getSelection && document.createRange) { + range = document.createRange(); + range.selectNodeContents(contentEditableElement); + sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + }; + + /** + * Get text selection + * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore + * + * @return {Range | TextRange | null} range + */ + util.getSelection = function getSelection() { + if (window.getSelection) { + var sel = window.getSelection(); + if (sel.getRangeAt && sel.rangeCount) { + return sel.getRangeAt(0); + } + } + return null; + }; + + /** + * Set text selection + * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore + * + * @param {Range | + * TextRange | null} range + */ + util.setSelection = function setSelection(range) { + if (range) { + if (window.getSelection) { + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + } + }; + + /** + * Get selected text range + * + * @return {Object} params object containing parameters: {Number} + * startOffset {Number} endOffset {Element} container HTML element + * holding the selected text element Returns null if no text + * selection is found + */ + util.getSelectionOffset = function getSelectionOffset() { + var range = util.getSelection(); + + if (range && 'startOffset' in range && 'endOffset' in range + && range.startContainer + && (range.startContainer == range.endContainer)) { + return { + startOffset : range.startOffset, + endOffset : range.endOffset, + container : range.startContainer.parentNode + }; + } + + return null; + }; + + /** + * Set selected text range in given element + * + * @param {Object} + * params An object containing: {Element} container {Number} + * startOffset {Number} endOffset + */ + util.setSelectionOffset = function setSelectionOffset(params) { + if (document.createRange && window.getSelection) { + var selection = window.getSelection(); + if (selection) { + var range = document.createRange(); + // TODO: do not suppose that the first child of the container is + // a + // textnode, + // but recursively find the textnodes + range.setStart(params.container.firstChild, params.startOffset); + range.setEnd(params.container.firstChild, params.endOffset); + + util.setSelection(range); + } + } + }; + + /** + * Get the inner text of an HTML element (for example a div element) + * + * @param {Element} + * element + * @param {Object} + * [buffer] + * @return {String} innerText + */ + util.getInnerText = function getInnerText(element, buffer) { + var first = (buffer == undefined); + if (first) { + buffer = { + 'text' : '', + 'flush' : function() { + var text = this.text; + this.text = ''; + return text; + }, + 'set' : function(text) { + this.text = text; + } + }; + } + + // text node + if (element.nodeValue) { + return buffer.flush() + element.nodeValue; + } + + // divs or other HTML elements + if (element.hasChildNodes()) { + var childNodes = element.childNodes; + var innerText = ''; + + for ( var i = 0, iMax = childNodes.length; i < iMax; i++) { + var child = childNodes[i]; + + if (child.nodeName == 'DIV' || child.nodeName == 'P') { + var prevChild = childNodes[i - 1]; + var prevName = prevChild ? prevChild.nodeName : undefined; + if (prevName && prevName != 'DIV' && prevName != 'P' + && prevName != 'BR') { + innerText += '\n'; + buffer.flush(); + } + innerText += util.getInnerText(child, buffer); + buffer.set('\n'); + } else if (child.nodeName == 'BR') { + innerText += buffer.flush(); + buffer.set('\n'); + } else { + innerText += util.getInnerText(child, buffer); + } + } + + return innerText; + } else { + if (element.nodeName == 'P' + && util.getInternetExplorerVersion() != -1) { + // On Internet Explorer, a

with hasChildNodes()==false is + // rendered with a new line. Note that a

with + // hasChildNodes()==true is rendered without a new line + // Other browsers always ensure there is a
inside the

, + // and if not, the

does not render a new line + return buffer.flush(); + } + } + + // br or unknown + return ''; + }; + + /** + * Returns the version of Internet Explorer or a -1 (indicating the use of + * another browser). Source: + * http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx + * + * @return {Number} Internet Explorer version, or -1 in case of an other + * browser + */ + util.getInternetExplorerVersion = function getInternetExplorerVersion() { + if (_ieVersion == -1) { + var rv = -1; // Return value assumes failure. + if (navigator.appName == 'Microsoft Internet Explorer') { + var ua = navigator.userAgent; + var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); + if (re.exec(ua) != null) { + rv = parseFloat(RegExp.$1); + } + } + + _ieVersion = rv; + } + + return _ieVersion; + }; + + /** + * Test whether the current browser is Firefox + * + * @returns {boolean} isFirefox + */ + util.isFirefox = function isFirefox() { + return (navigator.userAgent.indexOf("Firefox") != -1); + }; + + /** + * cached internet explorer version + * + * @type {Number} + * @private + */ + var _ieVersion = -1; + + /** + * Add and event listener. Works for all browsers + * + * @param {Element} + * element An html element + * @param {string} + * action The action, for example "click", without the prefix + * "on" + * @param {function} + * listener The callback function to be executed + * @param {boolean} + * [useCapture] false by default + * @return {function} the created event listener + */ + util.addEventListener = function addEventListener(element, action, + listener, useCapture) { + if (element.addEventListener) { + if (useCapture === undefined) + useCapture = false; + + if (action === "mousewheel" && util.isFirefox()) { + action = "DOMMouseScroll"; // For Firefox + } + + element.addEventListener(action, listener, useCapture); + return listener; + } else if (element.attachEvent) { + // Old IE browsers + var f = function() { + return listener.call(element, window.event); + }; + element.attachEvent("on" + action, f); + return f; + } + }; + + /** + * Remove an event listener from an element + * + * @param {Element} + * element An html dom element + * @param {string} + * action The name of the event, for example "mousedown" + * @param {function} + * listener The listener function + * @param {boolean} + * [useCapture] false by default + */ + util.removeEventListener = function removeEventListener(element, action, + listener, useCapture) { + if (element.removeEventListener) { + if (useCapture === undefined) + useCapture = false; + + if (action === "mousewheel" && util.isFirefox()) { + action = "DOMMouseScroll"; // For Firefox + } + + element.removeEventListener(action, listener, useCapture); + } else if (element.detachEvent) { + // Old IE browsers + element.detachEvent("on" + action, listener); + } + }; + + // module exports + var jsoneditor = { + 'JSONEditor' : JSONEditor, + 'JSONFormatter' : function() { + throw new Error('JSONFormatter is deprecated. ' + + 'Use JSONEditor with mode "text" or "code" instead'); + }, + 'util' : util + }; + + /** + * load jsoneditor.css + */ + var loadCss = function() { + // find the script named 'jsoneditor.js' or 'jsoneditor-min.js' or + // 'jsoneditor.min.js', and use its path to find the css file to be + // loaded. + var scripts = document.getElementsByTagName('script'); + for ( var s = 0; s < scripts.length; s++) { + var src = scripts[s].src; + if (/(^|\/)jsoneditor([-\.]min)?.js$/.test(src)) { + var jsFile = src.split('?')[0]; + + var cssFile = jsFile.substring(0, jsFile.length - 2) + 'css'; + + // load css file + var link = document.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = cssFile; + document.getElementsByTagName('head')[0].appendChild(link); + + break; + } + } + }; + + /** + * CommonJS module exports + */ + if (typeof (module) != 'undefined' && typeof (exports) != 'undefined') { + loadCss(); + module.exports = exports = jsoneditor; + } + + /** + * AMD module exports + */ + if (typeof (require) != 'undefined' && typeof (define) != 'undefined') { + loadCss(); + define(function() { + return jsoneditor; + }); + } else { + // attach the module to the window, load as a regular javascript file + window['jsoneditor'] = jsoneditor; + } + +})(); diff --git a/Bench4Q-Web/src/main/webapp/login.jsp b/Bench4Q-Web/src/main/webapp/login.jsp index f2e80fff..1886d562 100644 --- a/Bench4Q-Web/src/main/webapp/login.jsp +++ b/Bench4Q-Web/src/main/webapp/login.jsp @@ -24,7 +24,7 @@ - + diff --git a/Bench4Q-Web/src/main/webapp/plugin.jsp b/Bench4Q-Web/src/main/webapp/plugin.jsp index 62abdb5c..6480af63 100644 --- a/Bench4Q-Web/src/main/webapp/plugin.jsp +++ b/Bench4Q-Web/src/main/webapp/plugin.jsp @@ -13,7 +13,7 @@ Create scripts by yourself. - + - - - + + + - + - + @@ -269,7 +269,7 @@ body { - + diff --git a/Bench4Q-Web/src/main/webapp/portManage.jsp b/Bench4Q-Web/src/main/webapp/portManage.jsp index c4152c65..20dabb12 100644 --- a/Bench4Q-Web/src/main/webapp/portManage.jsp +++ b/Bench4Q-Web/src/main/webapp/portManage.jsp @@ -5,14 +5,19 @@ <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> PortManage Page - + - - - + + + - + @@ -32,13 +37,12 @@

@@ -46,7 +50,7 @@ class="table table-striped table-bordered bootstrap-datatable datatable"> - + ID port InUse @@ -84,7 +88,8 @@
@@ -89,9 +95,9 @@ body {
@@ -115,24 +121,27 @@ body {
- +
- - + +
- - - - - -
+ + + + + +
@@ -148,18 +157,18 @@ body {