diff --git a/framework/cli/views/webapp/protected/components/Controller.php b/framework/cli/views/webapp/protected/components/Controller.php index 4d27862..083187e 100644 --- a/framework/cli/views/webapp/protected/components/Controller.php +++ b/framework/cli/views/webapp/protected/components/Controller.php @@ -6,10 +6,10 @@ class Controller extends CController { /** - * @var string the default layout for the controller view. Defaults to '//layouts/column1', - * meaning using a single column layout. See 'protected/views/layouts/column1.php'. + * @var string the default layout for the controller view. Defaults to '//layouts/main', + * meaning using a single column layout. See 'protected/views/layouts/main.php'. */ - public $layout='//layouts/column1'; + public $layout='//layouts/main'; /** * @var array context menu items. This property will be assigned to {@link CMenu::items}. */ diff --git a/www/protected/components/Controller.php b/www/protected/components/Controller.php index 4d27862..083187e 100644 --- a/www/protected/components/Controller.php +++ b/www/protected/components/Controller.php @@ -6,10 +6,10 @@ class Controller extends CController { /** - * @var string the default layout for the controller view. Defaults to '//layouts/column1', - * meaning using a single column layout. See 'protected/views/layouts/column1.php'. + * @var string the default layout for the controller view. Defaults to '//layouts/main', + * meaning using a single column layout. See 'protected/views/layouts/main.php'. */ - public $layout='//layouts/column1'; + public $layout='//layouts/main'; /** * @var array context menu items. This property will be assigned to {@link CMenu::items}. */ diff --git a/www/protected/config/env/dev.php b/www/protected/config/env/dev.php index 8ce1136..c65e806 100644 --- a/www/protected/config/env/dev.php +++ b/www/protected/config/env/dev.php @@ -27,6 +27,7 @@ return array( 'modules'=>array( 'gii'=>array( 'class'=>'system.gii.GiiModule', + 'generatorPaths' => array('bootstrap.gii'), 'password'=>'giipw', 'ipFilters'=>array('127.0.0.1','::1'), ), diff --git a/www/protected/config/main.php b/www/protected/config/main.php index 4057807..6000c85 100644 --- a/www/protected/config/main.php +++ b/www/protected/config/main.php @@ -11,27 +11,40 @@ use Yiinitializr\Helpers\ArrayX; return ArrayX::merge(array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', - 'name'=>'My Web Application', + 'name'=>'Mikescher.de', // preloading 'log' component 'preload'=>array('log'), + 'aliases' => array( + 'bootstrap' => realpath(__DIR__ . '/../extensions/bootstrap'), // change this if necessary + ), + // autoloading model and component classes 'import'=>array( 'application.models.*', 'application.components.*', + 'bootstrap.components.*', + 'bootstrap.behaviors.*', + 'bootstrap.helpers.*', + ), 'modules'=>array( - + // ), // application components 'components'=>array( + 'bootstrap' => array( + 'class' => 'bootstrap.components.TbApi', + ), + 'user'=>array( // enable cookie-based authentication 'allowAutoLogin'=>true, ), + // uncomment the following to enable URLs in path-format /* 'urlManager'=>array( diff --git a/www/protected/extensions/bootstrap/.gitignore b/www/protected/extensions/bootstrap/.gitignore new file mode 100644 index 0000000..58793a2 --- /dev/null +++ b/www/protected/extensions/bootstrap/.gitignore @@ -0,0 +1,29 @@ +# Composer files +composer.phar +vendor/* + +# Codeception files +codecept.phar +tests/_log/* +tests/acceptance/* +tests/functional/* +tests/acceptance.suite.yml +tests/functional.suite.yml + +# Node modules +node_modules + +# releases +releases/ + +# project files +.idea/* +nbproject/* + +# mac deployment helpers +switch + +# cache directories +Thumbs.db +*.DS_Store +*.empty \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/.travis.yml b/www/protected/extensions/bootstrap/.travis.yml new file mode 100644 index 0000000..67267d0 --- /dev/null +++ b/www/protected/extensions/bootstrap/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.4 + +before_script: + - composer self-update + - composer install --prefer-source + +script: vendor/bin/codecept run unit + +branches: + only: + - master \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/Gruntfile.js b/www/protected/extensions/bootstrap/Gruntfile.js new file mode 100644 index 0000000..7f67289 --- /dev/null +++ b/www/protected/extensions/bootstrap/Gruntfile.js @@ -0,0 +1,31 @@ +// The wrapper function +module.exports = function(grunt) { + + // Project and task configuration + grunt.initConfig({ + less: { + development: { + files: { + "assets/css/yiistrap.css": "assets/less/yiistrap.less" + } + }, + production: { + options: { + compress: true, + yuicompress: true, + optimization: 2 + }, + files: { + "assets/css/yiistrap.min.css": "assets/less/yiistrap.less" + } + } + } + }); + + // Load plugins + grunt.loadNpmTasks('grunt-contrib-less'); + + // Define tasks + grunt.registerTask('default', ['less']); + +}; \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/LICENSE.txt b/www/protected/extensions/bootstrap/LICENSE.txt new file mode 100644 index 0000000..efd1221 --- /dev/null +++ b/www/protected/extensions/bootstrap/LICENSE.txt @@ -0,0 +1,24 @@ +Copyright (c) 2013, Christoffer Niska +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Christoffer Niska nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/README.md b/www/protected/extensions/bootstrap/README.md new file mode 100644 index 0000000..71b96e6 --- /dev/null +++ b/www/protected/extensions/bootstrap/README.md @@ -0,0 +1,10 @@ +Yiistrap +======== + +[![Latest Stable Version](https://poser.pugx.org/crisu83/yiistrap/v/stable.png)](https://packagist.org/packages/crisu83/yiistrap) +[![Build Status](https://travis-ci.org/Crisu83/yiistrap.png)](https://travis-ci.org/Crisu83/yiistrap) + +Twitter Bootstrap for Yii. + +Documentation can be found here: +[http://www.getyiistrap.com](http://www.getyiistrap.com) diff --git a/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.css b/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.css new file mode 100644 index 0000000..09e88ce --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * 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; + line-height: 0; + 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: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .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; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .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; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + 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; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + 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: 30px; + -webkit-box-sizing: border-box; + -moz-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; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-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; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .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 10px; + } + .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: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -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 .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + 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 .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -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-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .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: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.min.css b/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.min.css new file mode 100644 index 0000000..f4ede63 --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * 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;line-height:0;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:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .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;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .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;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{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}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{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:30px;-webkit-box-sizing:border-box;-moz-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}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-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}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.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 10px}.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:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-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 .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;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 .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-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-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.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:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/www/protected/extensions/bootstrap/assets/css/bootstrap.css b/www/protected/extensions/bootstrap/assets/css/bootstrap.css new file mode 100644 index 0000000..b725064 --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/bootstrap.css @@ -0,0 +1,6167 @@ +/*! + * Bootstrap v2.3.2 + * + * 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; + line-height: 0; + 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: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +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 { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps 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, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +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; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .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; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-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 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, 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; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + 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: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +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: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +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-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; + -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, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* 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: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +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; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -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); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.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[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .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; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -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); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -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); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -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); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -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); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus: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: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 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 input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.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: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 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; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + 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: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + 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 .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + 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, +.table-bordered tbody:first-child tr:first-child > th: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, +.table-bordered tbody:first-child tr:first-child > th: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, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -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, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *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; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + 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 { + width: 16px; + 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 { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + 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: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + 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: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -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: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + 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 #e3e3e3; + -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; + -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; + -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: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + 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; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + 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-color: #e6e6e6; + background-image: -moz-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(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 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); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -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, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-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-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.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-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + 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); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + 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); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + 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); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + 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); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +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-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 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 > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.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: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.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; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.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-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + 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-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -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, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 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; + line-height: 0; + 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: 20px; + 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, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.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, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.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-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.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 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + 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, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + 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, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + 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, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + 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, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + 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, +.navbar-form .btn { + 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: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 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-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \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 .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 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); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -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 ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + 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 li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.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: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -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 { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.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; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 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; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -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; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -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-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-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 { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-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(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', 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); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + 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: -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(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', 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; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.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: -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, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-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(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + 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: -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, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-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(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + 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: -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, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-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(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + 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: -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, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + 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: -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: 20px; +} + +.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: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 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 { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/www/protected/extensions/bootstrap/assets/css/bootstrap.min.css b/www/protected/extensions/bootstrap/assets/css/bootstrap.min.css new file mode 100644 index 0000000..b6428e6 --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.2 + * + * 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;line-height:0;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:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}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{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps 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,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}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}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .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;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;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:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}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:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}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:#fff;border:1px solid #ccc;-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 .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .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;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}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}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-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)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.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[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .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}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-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)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-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)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-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)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-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)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus: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:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 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 input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 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;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{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:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.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 #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.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,.table-bordered tbody:first-child tr:first-child>th: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,.table-bordered tbody:first-child tr:first-child>th: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,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-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,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*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}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{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{width:16px;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{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;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 #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-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:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;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 #e3e3e3;-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 .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border: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);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-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,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.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-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}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-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright: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>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.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:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.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-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-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,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;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:20px;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,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.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,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.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-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.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 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;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,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{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,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.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,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;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,.navbar-form .btn{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:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius: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-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \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 .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline: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)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-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 ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{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 li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-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{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-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}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.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;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-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}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-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-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-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{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-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(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',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)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;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:-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(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',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;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.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:-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,.progress .bar-danger{background-color:#dd514c;background-image:-moz-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(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{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:-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,.progress .bar-success{background-color:#5eb95e;background-image:-moz-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(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{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:-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,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-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(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{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:-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,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;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:-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:20px}.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:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/www/protected/extensions/bootstrap/assets/css/yiistrap.css b/www/protected/extensions/bootstrap/assets/css/yiistrap.css new file mode 100644 index 0000000..ccf6340 --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/yiistrap.css @@ -0,0 +1,109 @@ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: NaN a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.grid-view { + font-size: 13px; +} +.grid-view .table th > .sort-link { + color: #333; + display: block; + font-size: 14px; + font-weight: bold; + position: relative; +} +.grid-view .table th > .sort-link:hover { + text-decoration: none; +} +.grid-view .table th > .sort-link .caret { + border-color: transparent; + border-style: solid; + border-width: 4px; + display: none; + position: absolute; + right: 5px; +} +.grid-view .table th > .sort-link.asc .caret { + border-bottom-color: #333; + display: block; + top: 4px; +} +.grid-view .table th > .sort-link.desc .caret { + border-top-color: #333; + display: block; + top: 8px; +} +.grid-view .table .filters > td .filter-container { + padding: 0 16px 0 0; +} +.grid-view .table .filters > td .filter-container input[type="text"], +.grid-view .table .filters > td .filter-container select { + margin-bottom: 0; + width: 100%; +} +.grid-view .table tr.selected td { + background: #eee; +} +.grid-view .table td { + vertical-align: middle; +} +.grid-view .table .checkbox-column { + width: 15px; +} +.grid-view .table .number-column { + text-align: right; +} +.grid-view .table .button-column { + text-align: right; + min-width: 50px; +} +.grid-view .summary { + color: #999999; + font-size: 12px; + padding: 6px 0; + text-align: right; +} +.grid-view .empty { + font-style: italic; +} +.grid-view.grid-view-loading { + background: url(../img/loader.gif) no-repeat 100% 10px; +} +.grid-view.grid-view-loading .table { + opacity: 0.5; +} +.grid-view.grid-view-loading .table th > .sort-link .caret { + display: none; +} +.detail-view .null { color:#ffc0cb; } +.detail-view th { + text-align:right; + width:160px; +} +span.required { + color: #b94a48; + font-weight: bold; +} diff --git a/www/protected/extensions/bootstrap/assets/css/yiistrap.min.css b/www/protected/extensions/bootstrap/assets/css/yiistrap.min.css new file mode 100644 index 0000000..4a771fa --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/css/yiistrap.min.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:NaN a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.grid-view{font-size:13px}.grid-view .table th>.sort-link{color:#333;display:block;font-size:14px;font-weight:bold;position:relative}.grid-view .table th>.sort-link:hover{text-decoration:none}.grid-view .table th>.sort-link .caret{border-color:transparent;border-style:solid;border-width:4px;display:none;position:absolute;right:5px}.grid-view .table th>.sort-link.asc .caret{border-bottom-color:#333;display:block;top:4px}.grid-view .table th>.sort-link.desc .caret{border-top-color:#333;display:block;top:8px}.grid-view .table .filters>td .filter-container{padding:0 16px 0 0}.grid-view .table .filters>td .filter-container input[type="text"], .grid-view .table .filters>td .filter-container select{margin-bottom:0;width:100%}.grid-view .table tr.selected td{background:#eee}.grid-view .table td{vertical-align:middle}.grid-view .table .checkbox-column{width:15px}.grid-view .table .number-column{text-align:right}.grid-view .table .button-column{text-align:right;min-width:50px}.grid-view .summary{color:#999;font-size:12px;padding:6px 0;text-align:right}.grid-view .empty{font-style:italic}.grid-view.grid-view-loading{background:url(../img/loader.gif) no-repeat 100% 10px}.grid-view.grid-view-loading .table{opacity:.5}.grid-view.grid-view-loading .table th>.sort-link .caret{display:none}.detail-view .null{color:#ffc0cb;}.detail-view th{text-align:right;width:160px;}span.required{color:#b94a48;font-weight:bold} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings-white.png b/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings-white.png new file mode 100644 index 0000000..3bf6484 Binary files /dev/null and b/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings-white.png differ diff --git a/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings.png b/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings.png new file mode 100644 index 0000000..a996999 Binary files /dev/null and b/www/protected/extensions/bootstrap/assets/img/glyphicons-halflings.png differ diff --git a/www/protected/extensions/bootstrap/assets/img/loader.gif b/www/protected/extensions/bootstrap/assets/img/loader.gif new file mode 100644 index 0000000..155fcf5 Binary files /dev/null and b/www/protected/extensions/bootstrap/assets/img/loader.gif differ diff --git a/www/protected/extensions/bootstrap/assets/js/bootstrap.js b/www/protected/extensions/bootstrap/assets/js/bootstrap.js new file mode 100644 index 0000000..643e71c --- /dev/null +++ b/www/protected/extensions/bootstrap/assets/js/bootstrap.js @@ -0,0 +1,2280 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * 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. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * 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. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.jQuery);/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * 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. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * 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. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * 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. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.jQuery);/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * 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. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $(''; + return $output; + } + + /** + * Generates a custom (pre-rendered) active form control group. + * @param string $input the rendered input. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + */ + public static function customActiveControlGroup($input, $model, $attribute, $htmlOptions = array()) + { + $htmlOptions['input'] = $input; + return self::activeControlGroup(self::INPUT_TYPE_CUSTOM, $model, $attribute, $htmlOptions); + } + + /** + * Creates an active form input of the given type. + * @param string $type the input type. + * @param CModel $model the model instance. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @param array $data data for multiple select inputs. + * @return string the input. + * @throws CException if the input type is invalid. + */ + public static function createActiveInput($type, $model, $attribute, $htmlOptions = array(), $data = array()) + { + switch ($type) { + case self::INPUT_TYPE_TEXT: + return self::activeTextField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_PASSWORD: + return self::activePasswordField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_URL: + return self::activeUrlField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_EMAIL: + return self::activeEmailField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_NUMBER: + return self::activeNumberField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_RANGE: + return self::activeRangeField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_DATE: + return self::activeDateField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_TEXTAREA: + return self::activeTextArea($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_FILE: + return self::activeFileField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_RADIOBUTTON: + return self::activeRadioButton($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_CHECKBOX: + return self::activeCheckBox($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_DROPDOWNLIST: + return self::activeDropDownList($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_LISTBOX: + return self::activeListBox($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_CHECKBOXLIST: + return self::activeCheckBoxList($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_INLINECHECKBOXLIST: + return self::activeInlineCheckBoxList($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_RADIOBUTTONLIST: + return self::activeRadioButtonList($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_INLINERADIOBUTTONLIST: + return self::activeInlineRadioButtonList($model, $attribute, $data, $htmlOptions); + case self::INPUT_TYPE_UNEDITABLE: + return self::activeUneditableField($model, $attribute, $htmlOptions); + case self::INPUT_TYPE_SEARCH: + return self::activeSearchQueryField($model, $attribute, $htmlOptions); + default: + throw new CException('Invalid input type "' . $type . '".'); + } + } + + /** + * Displays a summary of validation errors for one or several models. + * @param mixed $model the models whose input errors are to be displayed. + * @param string $header a piece of HTML code that appears in front of the errors. + * @param string $footer a piece of HTML code that appears at the end of the errors. + * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag. + * @return string the error summary. Empty if no errors are found. + */ + public static function errorSummary($model, $header = null, $footer = null, $htmlOptions = array()) + { + // kind of a quick fix but it will do for now. + self::addCssClass(self::$errorSummaryCss, $htmlOptions); + return parent::errorSummary($model, $header, $footer, $htmlOptions); + } + + /** + * Displays the first validation error for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the rendered error. Empty if no errors are found. + */ + public static function error($model, $attribute, $htmlOptions = array()) + { + parent::resolveName($model, $attribute); // turn [a][b]attr into attr + $error = $model->getError($attribute); + return !empty($error) ? self::help($error, $htmlOptions) : ''; + } + + /** + * Generates an input HTML tag for a model attribute. + * This method generates an input HTML tag based on the given input name and value. + * @param string $type the input type. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input tag. + */ + protected static function activeTextInputField($type, $model, $attribute, $htmlOptions) + { + parent::resolveNameID($model, $attribute, $htmlOptions); + parent::clientChange('change', $htmlOptions); + + $htmlOptions = self::normalizeInputOptions($htmlOptions); + + $addOnClasses = self::getAddOnClasses($htmlOptions); + $addOnOptions = TbArray::popValue('addOnOptions', $htmlOptions, array()); + self::addCssClass($addOnClasses, $addOnOptions); + + $prepend = TbArray::popValue('prepend', $htmlOptions, ''); + $prependOptions = TbArray::popValue('prependOptions', $htmlOptions, array()); + if (!empty($prepend)) { + $prepend = self::inputAddOn($prepend, $prependOptions); + } + + $append = TbArray::popValue('append', $htmlOptions, ''); + $appendOptions = TbArray::popValue('appendOptions', $htmlOptions, array()); + if (!empty($append)) { + $append = self::inputAddOn($append, $appendOptions); + } + + $output = ''; + if (!empty($addOnClasses)) { + $output .= self::openTag('div', $addOnOptions); + } + $output .= $prepend . parent::activeInputField($type, $model, $attribute, $htmlOptions) . $append; + if (!empty($addOnClasses)) { + $output .= ''; + } + return $output; + } + + /** + * Returns the add-on classes based on the given options. + * @param array $htmlOptions the options. + * @return string the classes. + */ + protected static function getAddOnClasses($htmlOptions) + { + $classes = array(); + if (TbArray::getValue('append', $htmlOptions)) { + $classes[] = 'input-append'; + } + if (TbArray::getValue('prepend', $htmlOptions)) { + $classes[] = 'input-prepend'; + } + return !empty($classes) ? implode(' ', $classes) : $classes; + } + + /** + * Generates an add-on for an input field. + * @param string $addOn the add-on. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated add-on. + */ + protected static function inputAddOn($addOn, $htmlOptions) + { + $addOnOptions = TbArray::popValue('addOnOptions', $htmlOptions, array()); + self::addCssClass('add-on', $addOnOptions); + return strpos($addOn, 'btn') === false // buttons should not be wrapped in a span + ? self::tag('span', $addOnOptions, $addOn) + : $addOn; + } + + /** + * Generates a help text for an input field. + * @param string $help the help text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated help text. + */ + protected static function inputHelp($help, $htmlOptions) + { + $type = TbArray::popValue('type', $htmlOptions, self::HELP_TYPE_INLINE); + return $type === self::HELP_TYPE_INLINE + ? self::help($help, $htmlOptions) + : self::helpBlock($help, $htmlOptions); + } + + /** + * Normalizes input options. + * @param array $options the options. + * @return array the normalized options. + */ + protected static function normalizeInputOptions($options) + { + self::addSpanClass($options); + self::addTextAlignClass($options); + $size = TbArray::popValue('size', $options); + if (TbArray::popValue('block', $options, false)) { + self::addCssClass('input-block-level', $options); + } else { + if (!empty($size)) { + self::addCssClass('input-' . $size, $options); + } + } + return $options; + } + + /** + * Generates form controls. + * @param mixed $controls the controls. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated controls. + */ + public static function controls($controls, $htmlOptions = array()) + { + self::addCssClass('controls', $htmlOptions); + if (TbArray::popValue('row', $htmlOptions, false)) { + self::addCssClass('controls-row', $htmlOptions); + } + $before = TbArray::popValue('before', $htmlOptions, ''); + $after = TbArray::popValue('after', $htmlOptions, ''); + if (is_array($controls)) { + $controls = implode('', $controls); + } + $content = $before . $controls . $after; + return self::tag('div', $htmlOptions, $content); + } + + /** + * Generates form controls row. + * @param mixed $controls the controls. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated controls. + */ + public static function controlsRow($controls, $htmlOptions = array()) + { + $htmlOptions['row'] = true; + return self::controls($controls, $htmlOptions); + } + + /** + * Generates form actions. + * @param mixed $actions the actions. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated actions. + */ + public static function formActions($actions, $htmlOptions = array()) + { + self::addCssClass('form-actions', $htmlOptions); + if (is_array($actions)) { + $actions = implode(' ', $actions); + } + return self::tag('div', $htmlOptions, $actions); + } + + /** + * Generates a search form. + * @param mixed $action the form action URL. + * @param string $method form method (e.g. post, get). + * @param array $htmlOptions additional HTML options. + * @return string the generated form. + */ + public static function searchForm($action, $method = 'post', $htmlOptions = array()) + { + self::addCssClass('form-search', $htmlOptions); + $inputOptions = TbArray::popValue('inputOptions', $htmlOptions, array()); + $inputOptions = TbArray::merge(array('type' => 'text', 'placeholder' => 'Search'), $inputOptions); + $name = TbArray::popValue('name', $inputOptions, 'search'); + $value = TbArray::popValue('value', $inputOptions, ''); + $output = self::beginFormTb(self::FORM_LAYOUT_SEARCH, $action, $method, $htmlOptions); + $output .= self::searchQueryField($name, $value, $inputOptions); + $output .= parent::endForm(); + return $output; + } + + // Buttons + // http://twitter.github.io/bootstrap/2.3.2/base-css.html#buttons + // -------------------------------------------------- + + /** + * Generates a hyperlink tag. + * @param string $text link body. It will NOT be HTML-encoded. + * @param mixed $url a URL or an action route that can be used to create a URL. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated hyperlink + */ + public static function link($text, $url = '#', $htmlOptions = array()) + { + $htmlOptions['href'] = parent::normalizeUrl($url); + self::clientChange('click', $htmlOptions); + return self::tag('a', $htmlOptions, $text); + } + + /** + * Generates an button. + * @param string $label the button label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function button($label = 'Button', $htmlOptions = array()) + { + return self::htmlButton($label, $htmlOptions); + } + + /** + * Generates an image submit button. + * @param string $src the image URL + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function htmlButton($label = 'Button', $htmlOptions = array()) + { + return self::btn(self::BUTTON_TYPE_HTML, $label, $htmlOptions); + } + + /** + * Generates a submit button. + * @param string $label the button label + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function submitButton($label = 'Submit', $htmlOptions = array()) + { + return self::btn(self::BUTTON_TYPE_SUBMIT, $label, $htmlOptions); + } + + /** + * Generates a reset button. + * @param string $label the button label + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function resetButton($label = 'Reset', $htmlOptions = array()) + { + return self::btn(self::BUTTON_TYPE_RESET, $label, $htmlOptions); + } + + /** + * Generates an image submit button. + * @param string $src the image URL + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function imageButton($src, $htmlOptions = array()) + { + return self::btn(self::BUTTON_TYPE_IMAGE, $src, $htmlOptions); + } + + /** + * Generates a link submit button. + * @param string $label the button label. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button tag. + */ + public static function linkButton($label = 'Submit', $htmlOptions = array()) + { + return self::btn(self::BUTTON_TYPE_LINK, $label, $htmlOptions); + } + + /** + * Generates a link that can initiate AJAX requests. + * @param string $text the link body (it will NOT be HTML-encoded.) + * @param mixed $url the URL for the AJAX request. + * @param array $ajaxOptions AJAX options. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function ajaxLink($text, $url, $ajaxOptions = array(), $htmlOptions = array()) + { + if (!isset($htmlOptions['href'])) { + $htmlOptions['href'] = '#'; + } + $ajaxOptions['url'] = $url; + $htmlOptions['ajax'] = $ajaxOptions; + parent::clientChange('click', $htmlOptions); + return self::tag('a', $htmlOptions, $text); + } + + /** + * Generates a push button that can initiate AJAX requests. + * @param string $label the button label. + * @param mixed $url the URL for the AJAX request. + * @param array $ajaxOptions AJAX options. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function ajaxButton($label, $url, $ajaxOptions = array(), $htmlOptions = array()) + { + $ajaxOptions['url'] = $url; + $htmlOptions['ajaxOptions'] = $ajaxOptions; + return self::btn(self::BUTTON_TYPE_AJAXBUTTON, $label, $htmlOptions); + } + + /** + * Generates a push button that can submit the current form in POST method. + * @param string $label the button label + * @param mixed $url the URL for the AJAX request. + * @param array $ajaxOptions AJAX options. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function ajaxSubmitButton($label, $url, $ajaxOptions = array(), $htmlOptions = array()) + { + $ajaxOptions['type'] = 'POST'; + $htmlOptions['type'] = 'submit'; + return self::ajaxButton($label, $url, $ajaxOptions, $htmlOptions); + } + + // todo: add methods for input button and input submit. + + /** + * Generates a button. + * @param string $type the button type. + * @param string $label the button label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function btn($type, $label, $htmlOptions = array()) + { + self::addCssClass('btn', $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('btn-' . $color, $htmlOptions); + } + $size = TbArray::popValue('size', $htmlOptions); + if (!empty($size)) { + self::addCssClass('btn-' . $size, $htmlOptions); + } + if (TbArray::popValue('block', $htmlOptions, false)) { + self::addCssClass('btn-block', $htmlOptions); + } + if (TbArray::popValue('disabled', $htmlOptions, false)) { + self::addCssClass('disabled', $htmlOptions); + $htmlOptions['disabled'] = 'disabled'; + } + $loading = TbArray::popValue('loading', $htmlOptions); + if (!empty($loading)) { + $htmlOptions['data-loading-text'] = $loading; + } + if (TbArray::popValue('toggle', $htmlOptions, false)) { + $htmlOptions['data-toggle'] = 'button'; + } + $icon = TbArray::popValue('icon', $htmlOptions); + $iconOptions = TbArray::popValue('iconOptions', $htmlOptions, array()); + if (strpos($type, 'input') === false) { + if (!empty($icon)) { + $label = self::icon($icon, $iconOptions) . ' ' . $label; + } + $items = TbArray::popValue('items', $htmlOptions); + } + $dropdownOptions = $htmlOptions; + TbArray::removeValues(array('groupOptions', 'menuOptions', 'dropup'), $htmlOptions); + self::addSpanClass($htmlOptions); // must be called here as parent renders buttons + self::addPullClass($htmlOptions); // must be called here as parent renders buttons + return isset($items) + ? self::btnDropdown($type, $label, $items, $dropdownOptions) + : self::createButton($type, $label, $htmlOptions); + } + + /** + * Generates a button dropdown. + * @param string $type the button type. + * @param string $label the button label text. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + protected static function btnDropdown($type, $label, $items, $htmlOptions) + { + $menuOptions = TbArray::popValue('menuOptions', $htmlOptions, array()); + $groupOptions = TbArray::popValue('groupOptions', $htmlOptions, array()); + self::addCssClass('btn-group', $groupOptions); + if (TbArray::popValue('dropup', $htmlOptions, false)) { + self::addCssClass('dropup', $groupOptions); + } + $output = self::openTag('div', $groupOptions); + if (TbArray::popValue('split', $htmlOptions, false)) { + $output .= self::createButton($type, $label, $htmlOptions); + $output .= self::dropdownToggleButton('', $htmlOptions); + } else { + $output .= self::dropdownToggleLink($label, $htmlOptions); + } + $output .= self::dropdown($items, $menuOptions); + $output .= ''; + return $output; + } + + /** + * Creates a button the of given type. + * @param string $type the button type. + * @param string $label the button label. + * @param array $htmlOptions additional HTML attributes. + * @return string the button. + * @throws CException if the button type is valid. + */ + protected static function createButton($type, $label, $htmlOptions) + { + $url = TbArray::popValue('url', $htmlOptions, '#'); + $ajaxOptions = TbArray::popValue('ajaxOptions', $htmlOptions, array()); + switch ($type) { + case self::BUTTON_TYPE_HTML: + return parent::htmlButton($label, $htmlOptions); + + case self::BUTTON_TYPE_SUBMIT: + $htmlOptions['type'] = 'submit'; + return parent::htmlButton($label, $htmlOptions); + + case self::BUTTON_TYPE_RESET: + $htmlOptions['type'] = 'reset'; + return parent::htmlButton($label, $htmlOptions); + + case self::BUTTON_TYPE_IMAGE: + return parent::imageButton($label, $htmlOptions); + + case self::BUTTON_TYPE_LINKBUTTON: + return parent::linkButton($label, $htmlOptions); + + case self::BUTTON_TYPE_AJAXLINK: + return parent::ajaxLink($label, $url, $ajaxOptions, $htmlOptions); + + case self::BUTTON_TYPE_AJAXBUTTON: + $htmlOptions['ajax'] = $ajaxOptions; + return parent::htmlButton($label, $htmlOptions); + + case self::BUTTON_TYPE_INPUTBUTTON: + return parent::button($label, $htmlOptions); + + case self::BUTTON_TYPE_INPUTSUBMIT: + $htmlOptions['type'] = 'submit'; + return parent::button($label, $htmlOptions); + + case self::BUTTON_TYPE_LINK: + return self::link($label, $url, $htmlOptions); + + default: + throw new CException('Invalid button type "' . $type . '".'); + } + } + + // Images + // http://twitter.github.io/bootstrap/2.3.2/base-css.html#images + // -------------------------------------------------- + + /** + * Generates an image tag with rounded corners. + * @param string $src the image URL. + * @param string $alt the alternative text display. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated image tag. + */ + public static function imageRounded($src, $alt = '', $htmlOptions = array()) + { + $htmlOptions['type'] = self::IMAGE_TYPE_ROUNDED; + return self::image($src, $alt, $htmlOptions); + } + + /** + * Generates an image tag with circle. + * @param string $src the image URL. + * @param string $alt the alternative text display. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated image tag. + */ + public static function imageCircle($src, $alt = '', $htmlOptions = array()) + { + $htmlOptions['type'] = self::IMAGE_TYPE_CIRCLE; + return self::image($src, $alt, $htmlOptions); + } + + /** + * Generates an image tag within polaroid frame. + * @param string $src the image URL. + * @param string $alt the alternative text display. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated image tag. + */ + public static function imagePolaroid($src, $alt = '', $htmlOptions = array()) + { + $htmlOptions['type'] = self::IMAGE_TYPE_POLAROID; + return self::image($src, $alt, $htmlOptions); + } + + /** + * Generates an image tag. + * @param string $src the image URL. + * @param string $alt the alternative text display. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated image tag. + */ + public static function image($src, $alt = '', $htmlOptions = array()) + { + $type = TbArray::popValue('type', $htmlOptions); + if (!empty($type)) { + self::addCssClass('img-' . $type, $htmlOptions); + } + return parent::image($src, $alt, $htmlOptions); + } + + // Icons by Glyphicons + // http://twitter.github.io/bootstrap/2.3.2/base-css.html#icons + // -------------------------------------------------- + + /** + * Generates an icon. + * @param string $icon the icon type. + * @param array $htmlOptions additional HTML attributes. + * @param string $tagName the icon HTML tag. + * @return string the generated icon. + */ + public static function icon($icon, $htmlOptions = array(), $tagName = 'i') + { + if (is_string($icon)) { + if (strpos($icon, 'icon') === false) { + $icon = 'icon-' . implode(' icon-', explode(' ', $icon)); + } + self::addCssClass($icon, $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color) && $color === self::ICON_COLOR_WHITE) { + self::addCssClass('icon-white', $htmlOptions); + } + return self::openTag($tagName, $htmlOptions) . parent::closeTag($tagName); // tag won't work in this case + } + return ''; + } + + // + // COMPONENTS + // -------------------------------------------------- + + // Dropdowns + // http://twitter.github.io/bootstrap/2.3.2/components.html#dropdowns + // -------------------------------------------------- + + /** + * Generates a dropdown menu. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + protected static function dropdown($items, $htmlOptions = array()) + { + TbArray::defaultValue('role', 'menu', $htmlOptions); + self::addCssClass('dropdown-menu', $htmlOptions); + return self::menu($items, $htmlOptions); + } + + /** + * Generates a dropdown toggle link. + * @param string $label the link label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function dropdownToggleLink($label, $htmlOptions = array()) + { + return self::dropdownToggle(self::BUTTON_TYPE_LINK, $label, $htmlOptions); + } + + /** + * Generates a dropdown toggle button. + * @param string $label the button label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function dropdownToggleButton($label = '', $htmlOptions = array()) + { + return self::dropdownToggle(self::BUTTON_TYPE_HTML, $label, $htmlOptions); + } + + /** + * Generates a dropdown toggle element. + * @param string $tag the HTML tag. + * @param string $label the element text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated element. + */ + protected static function dropdownToggle($type, $label, $htmlOptions) + { + self::addCssClass('dropdown-toggle', $htmlOptions); + $label .= ' '; + $htmlOptions['data-toggle'] = 'dropdown'; + return self::btn($type, $label, $htmlOptions); + } + + /** + * Generates a dropdown toggle menu item. + * @param string $label the menu item text. + * @param string $url the menu item URL. + * @param array $htmlOptions additional HTML attributes. + * @param int $depth the menu depth at which this link is located + * @return string the generated menu item. + */ + public static function dropdownToggleMenuLink($label, $url = '#', $htmlOptions = array(), $depth = 0) + { + self::addCssClass('dropdown-toggle', $htmlOptions); + if ($depth === 0) { + $label .= ' '; + } + $htmlOptions['data-toggle'] = 'dropdown'; + return self::link($label, $url, $htmlOptions); + } + + // Button groups + // http://twitter.github.io/bootstrap/2.3.2/components.html#buttonGroups + // -------------------------------------------------- + + /** + * Generates a button group. + * @param array $buttons the button configurations. + * @param array $htmlOptions additional HTML options. + * @return string the generated button group. + */ + public static function buttonGroup(array $buttons, $htmlOptions = array()) + { + if (!empty($buttons)) { + self::addCssClass('btn-group', $htmlOptions); + if (TbArray::popValue('vertical', $htmlOptions, false)) { + self::addCssClass('btn-group-vertical', $htmlOptions); + } + $toggle = TbArray::popValue('toggle', $htmlOptions); + if (!empty($toggle)) { + $htmlOptions['data-toggle'] = 'buttons-' . $toggle; + } + $parentOptions = array( + 'color' => TbArray::popValue('color', $htmlOptions), + 'size' => TbArray::popValue('size', $htmlOptions), + 'disabled' => TbArray::popValue('disabled', $htmlOptions) + ); + $output = self::openTag('div', $htmlOptions); + foreach ($buttons as $buttonOptions) { + if (isset($buttonOptions['visible']) && $buttonOptions['visible'] === false) { + continue; + } + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $buttonOptions, array()); + if (!empty($options)) { + $buttonOptions = TbArray::merge($options, $buttonOptions); + } + $buttonLabel = TbArray::popValue('label', $buttonOptions, ''); + $buttonOptions = TbArray::copyValues(array('color', 'size', 'disabled'), $parentOptions, $buttonOptions); + $items = TbArray::popValue('items', $buttonOptions, array()); + if (!empty($items)) { + $output .= self::buttonDropdown($buttonLabel, $items, $buttonOptions); + } else { + $ajaxOptions = TbArray::popValue('ajaxOptions', $buttonOptions, array()); + if(!empty($ajaxOptions)) { + $output .= self::ajaxButton($buttonLabel, TbArray::popValue('url', $ajaxOptions, '#'), $ajaxOptions, $buttonOptions); + } else { + $output .= self::linkButton($buttonLabel, $buttonOptions); + } + } + } + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates a vertical button group. + * @param array $buttons the button configurations. + * @param array $htmlOptions additional HTML options. + * @return string the generated button group. + */ + public static function verticalButtonGroup(array $buttons, $htmlOptions = array()) + { + $htmlOptions['vertical'] = true; + return self::buttonGroup($buttons, $htmlOptions); + } + + /** + * Generates a button toolbar. + * @param array $groups the button group configurations. + * @param array $htmlOptions additional HTML options. + * @return string the generated button toolbar. + */ + public static function buttonToolbar(array $groups, $htmlOptions = array()) + { + if (!empty($groups)) { + self::addCssClass('btn-toolbar', $htmlOptions); + $parentOptions = array( + 'color' => TbArray::popValue('color', $htmlOptions), + 'size' => TbArray::popValue('size', $htmlOptions), + 'disabled' => TbArray::popValue('disabled', $htmlOptions) + ); + $output = self::openTag('div', $htmlOptions); + foreach ($groups as $groupOptions) { + if (isset($groupOptions['visible']) && $groupOptions['visible'] === false) { + continue; + } + $items = TbArray::popValue('items', $groupOptions, array()); + if (empty($items)) { + continue; + } + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $groupOptions, array()); + if (!empty($options)) { + $groupOptions = TbArray::merge($options, $groupOptions); + } + $groupOptions = TbArray::copyValues(array('color', 'size', 'disabled'), $parentOptions, $groupOptions); + $output .= self::buttonGroup($items, $groupOptions); + } + $output .= ''; + return $output; + } + return ''; + } + + // Button dropdowns + // http://twitter.github.io/bootstrap/2.3.2/components.html#buttonDropdowns + // -------------------------------------------------- + + /** + * Generates a button with a dropdown menu. + * @param string $label the button label text. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function buttonDropdown($label, $items, $htmlOptions = array()) + { + $htmlOptions['items'] = $items; + $type = TbArray::popValue('type', $htmlOptions, self::BUTTON_TYPE_LINKBUTTON); + return self::btn($type, $label, $htmlOptions); + } + + /** + * Generates a button with a split dropdown menu. + * @param string $label the button label text. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated button. + */ + public static function splitButtonDropdown($label, $items, $htmlOptions = array()) + { + $htmlOptions['split'] = true; + return self::buttonDropdown($label, $items, $htmlOptions); + } + + // Navs + // http://twitter.github.io/bootstrap/2.3.2/components.html#navs + // -------------------------------------------------- + + /** + * Generates a tab navigation. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function tabs($items, $htmlOptions = array()) + { + return self::nav(self::NAV_TYPE_TABS, $items, $htmlOptions); + } + + /** + * Generates a stacked tab navigation. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function stackedTabs($items, $htmlOptions = array()) + { + $htmlOptions['stacked'] = true; + return self::tabs($items, $htmlOptions); + } + + /** + * Generates a pills navigation. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function pills($items, $htmlOptions = array()) + { + return self::nav(self::NAV_TYPE_PILLS, $items, $htmlOptions); + } + + /** + * Generates a stacked pills navigation. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function stackedPills($items, $htmlOptions = array()) + { + $htmlOptions['stacked'] = true; + return self::pills($items, $htmlOptions); + } + + /** + * Generates a list navigation. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function navList($items, $htmlOptions = array()) + { + foreach ($items as $i => $itemOptions) { + if (is_string($itemOptions)) { + continue; + } + if (!isset($itemOptions['url']) && !isset($itemOptions['items'])) { + $label = TbArray::popValue('label', $itemOptions, ''); + $items[$i] = self::menuHeader($label, $itemOptions); + } + } + return self::nav(self::NAV_TYPE_LIST, $items, $htmlOptions); + } + + /** + * Generates a navigation menu. + * @param string $type the menu type. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function nav($type, $items, $htmlOptions = array()) + { + self::addCssClass('nav', $htmlOptions); + if (!empty($type)) { + self::addCssClass('nav-' . $type, $htmlOptions); + } + $stacked = TbArray::popValue('stacked', $htmlOptions, false); + if ($type !== self::NAV_TYPE_LIST && $stacked) { + self::addCssClass('nav-stacked', $htmlOptions); + } + return self::menu($items, $htmlOptions); + } + + /** + * Generates a menu. + * @param array $items the menu items. + * @param array $htmlOptions additional HTML attributes. + * @param integer $depth the current depth. + * @return string the generated menu. + */ + public static function menu(array $items, $htmlOptions = array(), $depth = 0) + { + // todo: consider making this method protected. + if (!empty($items)) { + $htmlOptions['role'] = 'menu'; + $output = self::openTag('ul', $htmlOptions); + foreach ($items as $itemOptions) { + if (is_string($itemOptions)) { + $output .= $itemOptions; + } else { + if (isset($itemOptions['visible']) && $itemOptions['visible'] === false) { + continue; + } + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $itemOptions, array()); + if (!empty($options)) { + $itemOptions = TbArray::merge($options, $itemOptions); + } + $label = TbArray::popValue('label', $itemOptions, ''); + if (TbArray::popValue('active', $itemOptions, false)) { + self::addCssClass('active', $itemOptions); + } + if (TbArray::popValue('disabled', $itemOptions, false)) { + self::addCssClass('disabled', $itemOptions); + } + if (!isset($itemOptions['linkOptions'])) { + $itemOptions['linkOptions'] = array(); + } + $icon = TbArray::popValue('icon', $itemOptions); + if (!empty($icon)) { + $label = self::icon($icon) . ' ' . $label; + } + $items = TbArray::popValue('items', $itemOptions, array()); + $url = TbArray::popValue('url', $itemOptions, false); + if (empty($items)) { + if (!$url) { + $output .= self::menuHeader($label); + } else { + $itemOptions['linkOptions']['tabindex'] = -1; + $output .= self::menuLink($label, $url, $itemOptions); + } + } else { + $output .= self::menuDropdown($label, $url, $items, $itemOptions, $depth); + } + } + } + $output .= ''; + return $output; + } else { + return ''; + } + } + + /** + * Generates a menu link. + * @param string $label the link label. + * @param array $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu item. + */ + public static function menuLink($label, $url, $htmlOptions = array()) + { + TbArray::defaultValue('role', 'menuitem', $htmlOptions); + $linkOptions = TbArray::popValue('linkOptions', $htmlOptions, array()); + $content = self::link($label, $url, $linkOptions); + return self::tag('li', $htmlOptions, $content); + } + + /** + * Generates a menu dropdown. + * @param string $label the link label. + * @param string $url the link URL. + * @param array $items the menu configuration. + * @param array $htmlOptions additional HTML attributes. + * @param integer $depth the current depth. + * @return string the generated dropdown. + */ + protected static function menuDropdown($label, $url, $items, $htmlOptions, $depth = 0) + { + self::addCssClass($depth === 0 ? 'dropdown' : 'dropdown-submenu', $htmlOptions); + TbArray::defaultValue('role', 'menuitem', $htmlOptions); + $linkOptions = TbArray::popValue('linkOptions', $htmlOptions, array()); + $menuOptions = TbArray::popValue('menuOptions', $htmlOptions, array()); + self::addCssClass('dropdown-menu', $menuOptions); + if ($depth === 0) { + $defaultId = parent::ID_PREFIX . parent::$count++; + TbArray::defaultValue('id', $defaultId, $menuOptions); + $menuOptions['aria-labelledby'] = $menuOptions['id']; + $menuOptions['role'] = 'menu'; + } + $output = self::openTag('li', $htmlOptions); + $output .= self::dropdownToggleMenuLink($label, $url, $linkOptions, $depth); + $output .= self::menu($items, $menuOptions, $depth + 1); + $output .= ''; + return $output; + } + + /** + * Generates a menu header. + * @param string $label the header text. + * @param array $htmlOptions additional HTML options. + * @return string the generated header. + */ + public static function menuHeader($label, $htmlOptions = array()) + { + self::addCssClass('nav-header', $htmlOptions); + return self::tag('li', $htmlOptions, $label); + } + + /** + * Generates a menu divider. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu item. + */ + public static function menuDivider($htmlOptions = array()) + { + self::addCssClass('divider', $htmlOptions); + return self::tag('li', $htmlOptions); + } + + /** + * Generates a tabbable tabs menu. + * @param array $tabs the tab configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function tabbableTabs($tabs, $htmlOptions = array()) + { + return self::tabbable(self::NAV_TYPE_TABS, $tabs, $htmlOptions); + } + + /** + * Generates a tabbable pills menu. + * @param array $tabs the tab configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function tabbablePills($pills, $htmlOptions = array()) + { + return self::tabbable(self::NAV_TYPE_PILLS, $pills, $htmlOptions); + } + + /** + * Generates a tabbable menu. + * @param string $type the menu type. + * @param array $tabs the tab configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated menu. + */ + public static function tabbable($type, $tabs, $htmlOptions = array()) + { + self::addCssClass('tabbable', $htmlOptions); + $placement = TbArray::popValue('placement', $htmlOptions); + if (!empty($placement)) { + self::addCssClass('tabs-' . $placement, $htmlOptions); + } + $menuOptions = TbArray::popValue('menuOptions', $htmlOptions, array()); + $contentOptions = TbArray::popValue('contentOptions', $htmlOptions, array()); + self::addCssClass('tab-content', $contentOptions); + $panes = array(); + $items = self::normalizeTabs($tabs, $panes); + $menu = self::nav($type, $items, $menuOptions); + $content = self::tag('div', $contentOptions, implode('', $panes)); + $output = self::openTag('div', $htmlOptions); + $output .= $placement === self::TABS_PLACEMENT_BELOW ? $content . $menu : $menu . $content; + $output .= ''; + return $output; + } + + /** + * Normalizes the tab configuration. + * @param array $tabs the tab configuration. + * @param array $panes a reference to the panes array. + * @param integer $i the running index. + * @return array the items. + */ + protected static function normalizeTabs($tabs, &$panes, $i = 0) + { + $menuItems = array(); + foreach ($tabs as $tabOptions) { + if (isset($tabOptions['visible']) && $tabOptions['visible'] === false) { + continue; + } + $menuItem = array(); + $menuItem['icon'] = TbArray::popValue('icon', $tabOptions); + $menuItem['label'] = TbArray::popValue('label', $tabOptions, ''); + $menuItem['active'] = TbArray::getValue('active', $tabOptions, false); + $menuItem['disabled'] = TbArray::popValue('disabled', $tabOptions, false); + $menuItem['linkOptions'] = TbArray::popValue('linkOptions', $tabOptions, array()); + $menuItem['htmlOptions'] = TbArray::popValue('htmlOptions', $tabOptions, array()); + $items = TbArray::popValue('items', $tabOptions, array()); + if (!empty($items)) { + $menuItem['linkOptions']['data-toggle'] = 'dropdown'; + $menuItem['items'] = self::normalizeTabs($items, $panes, $i); + } else { + $paneOptions = TbArray::popValue('paneOptions', $tabOptions, array()); + $id = $paneOptions['id'] = TbArray::popValue('id', $tabOptions, 'tab_' . ++$i); + $menuItem['linkOptions']['data-toggle'] = 'tab'; + $menuItem['url'] = '#' . $id; + self::addCssClass('tab-pane', $paneOptions); + if (TbArray::popValue('fade', $tabOptions, true)) { + self::addCssClass('fade', $paneOptions); + } + if (TbArray::popValue('active', $tabOptions, false)) { + self::addCssClass('active in', $paneOptions); + } + $paneContent = TbArray::popValue('content', $tabOptions, ''); + $panes[] = self::tag('div', $paneOptions, $paneContent); + } + $menuItems[] = $menuItem; + } + return $menuItems; + } + + // Navbar + // http://twitter.github.io/bootstrap/2.3.2/components.html#navbar + // -------------------------------------------------- + + /** + * Generates a navbar. + * @param string $content the navbar content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated navbar. + */ + public static function navbar($content, $htmlOptions = array()) + { + self::addCssClass('navbar', $htmlOptions); + $display = TbArray::popValue('display', $htmlOptions); + if (!empty($display)) { + self::addCssClass('navbar-' . $display, $htmlOptions); + } + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('navbar-' . $color, $htmlOptions); + } + $innerOptions = TbArray::popValue('innerOptions', $htmlOptions, array()); + self::addCssClass('navbar-inner', $innerOptions); + $output = self::openTag('div', $htmlOptions); + $output .= self::tag('div', $innerOptions, $content); + $output .= ''; + return $output; + } + + /** + * Generates a brand link for the navbar. + * @param string $label the link label text. + * @param string $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function navbarBrandLink($label, $url, $htmlOptions = array()) + { + self::addCssClass('brand', $htmlOptions); + return self::link($label, $url, $htmlOptions); + } + + /** + * Generates a text for the navbar. + * @param string $text the text. + * @param array $htmlOptions additional HTML attributes. + * @param string $tag the HTML tag. + * @return string the generated text block. + */ + public static function navbarText($text, $htmlOptions = array(), $tag = 'p') + { + self::addCssClass('navbar-text', $htmlOptions); + return self::tag($tag, $htmlOptions, $text); + } + + /** + * Generates a menu divider for the navbar. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated divider. + */ + public static function navbarMenuDivider($htmlOptions = array()) + { + self::addCssClass('divider-vertical', $htmlOptions); + return self::tag('li', $htmlOptions); + } + + /** + * Generates a navbar form. + * @param mixed $action the form action URL. + * @param string $method form method (e.g. post, get). + * @param array $htmlOptions additional HTML attributes + * @return string the generated form. + */ + public static function navbarForm($action, $method = 'post', $htmlOptions = array()) + { + self::addCssClass('navbar-form', $htmlOptions); + return self::form($action, $method, $htmlOptions); + } + + /** + * Generates a navbar search form. + * @param mixed $action the form action URL. + * @param string $method form method (e.g. post, get). + * @param array $htmlOptions additional HTML attributes + * @return string the generated form. + */ + public static function navbarSearchForm($action, $method = 'post', $htmlOptions = array()) + { + self::addCssClass('navbar-search', $htmlOptions); + return self::searchForm($action, $method, $htmlOptions); + } + + /** + * Generates a collapse element. + * @param string $target the CSS selector for the target element. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated icon. + */ + public static function navbarCollapseLink($target, $htmlOptions = array()) + { + self::addCssClass('btn btn-navbar', $htmlOptions); + $htmlOptions['data-toggle'] = 'collapse'; + $htmlOptions['data-target'] = $target; + $content = ''; + return self::tag('a', $htmlOptions, $content); + } + + // Breadcrumbs + // http://twitter.github.io/bootstrap/2.3.2/components.html#breadcrumbs + // -------------------------------------------------- + + /** + * Generates a breadcrumb menu. + * @param array $links the breadcrumb links. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated breadcrumb. + */ + public static function breadcrumbs($links, $htmlOptions = array()) + { + $divider = TbArray::popValue('divider', $htmlOptions, '/'); + self::addCssClass('breadcrumb', $htmlOptions); + $output = self::openTag('ul', $htmlOptions); + foreach ($links as $label => $url) { + if (is_string($label)) { + $output .= self::openTag('li'); + $output .= self::link($label, $url); + $output .= self::tag('span', array('class' => 'divider'), $divider); + $output .= ''; + } else { + $output .= self::tag('li', array('class' => 'active'), $url); + } + } + $output .= ''; + return $output; + } + + // Pagination + // http://twitter.github.io/bootstrap/2.3.2/components.html#pagination + // -------------------------------------------------- + + /** + * Generates a pagination. + * @param array $items the pagination buttons. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated pagination. + */ + public static function pagination(array $items, $htmlOptions = array()) + { + if (!empty($items)) { + self::addCssClass('pagination', $htmlOptions); + $size = TbArray::popValue('size', $htmlOptions); + if (!empty($size)) { + self::addCssClass('pagination-' . $size, $htmlOptions); + } + $align = TbArray::popValue('align', $htmlOptions); + if (!empty($align)) { + self::addCssClass('pagination-' . $align, $htmlOptions); + } + $listOptions = TbArray::popValue('listOptions', $htmlOptions, array()); + $output = self::openTag('div', $htmlOptions); + $output .= self::openTag('ul', $listOptions); + foreach ($items as $itemOptions) { + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $itemOptions, array()); + if (!empty($options)) { + $itemOptions = TbArray::merge($options, $itemOptions); + } + $label = TbArray::popValue('label', $itemOptions, ''); + $url = TbArray::popValue('url', $itemOptions, false); + $output .= self::paginationLink($label, $url, $itemOptions); + } + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates a pagination link. + * @param string $label the link label text. + * @param mixed $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function paginationLink($label, $url, $htmlOptions = array()) + { + $linkOptions = TbArray::popValue('linkOptions', $htmlOptions, array()); + if (TbArray::popValue('active', $htmlOptions, false)) { + self::addCssClass('active', $htmlOptions); + } + if (TbArray::popValue('disabled', $htmlOptions, false)) { + self::addCssClass('disabled', $htmlOptions); + } + $content = self::link($label, $url, $linkOptions); + return self::tag('li', $htmlOptions, $content); + } + + /** + * Generates a pager. + * @param array $links the pager buttons. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated pager. + */ + public static function pager(array $links, $htmlOptions = array()) + { + if (!empty($links)) { + self::addCssClass('pager', $htmlOptions); + $output = self::openTag('ul', $htmlOptions); + foreach ($links as $itemOptions) { + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $itemOptions, array()); + if (!empty($options)) { + $itemOptions = TbArray::merge($options, $itemOptions); + } + $label = TbArray::popValue('label', $itemOptions, ''); + $url = TbArray::popValue('url', $itemOptions, false); + $output .= self::pagerLink($label, $url, $itemOptions); + } + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates a pager link. + * @param string $label the link label text. + * @param mixed $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function pagerLink($label, $url, $htmlOptions = array()) + { + $linkOptions = TbArray::popValue('linkOptions', $htmlOptions, array()); + if (TbArray::popValue('previous', $htmlOptions, false)) { + self::addCssClass('previous', $htmlOptions); + } + if (TbArray::popValue('next', $htmlOptions, false)) { + self::addCssClass('next', $htmlOptions); + } + if (TbArray::popValue('disabled', $htmlOptions, false)) { + self::addCssClass('disabled', $htmlOptions); + } + $content = self::link($label, $url, $linkOptions); + return self::tag('li', $htmlOptions, $content); + } + + // Labels and badges + // http://twitter.github.io/bootstrap/2.3.2/components.html#labels-badges + // -------------------------------------------------- + + /** + * Generates a label span. + * @param string $label the label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated span. + */ + public static function labelTb($label, $htmlOptions = array()) + { + self::addCssClass('label', $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('label-' . $color, $htmlOptions); + } + return self::tag('span', $htmlOptions, $label); + } + + /** + * Generates a badge span. + * @param string $label the badge text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated span. + */ + public static function badge($label, $htmlOptions = array()) + { + self::addCssClass('badge', $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('badge-' . $color, $htmlOptions); + } + return self::tag('span', $htmlOptions, $label); + } + + // Typography + // http://twitter.github.io/bootstrap/2.3.2/components.html#typography + // -------------------------------------------------- + + /** + * Generates a hero unit. + * @param string $heading the heading text. + * @param string $content the content text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated hero unit. + */ + public static function heroUnit($heading, $content, $htmlOptions = array()) + { + self::addCssClass('hero-unit', $htmlOptions); + $headingOptions = TbArray::popValue('headingOptions', $htmlOptions, array()); + $output = self::openTag('div', $htmlOptions); + $output .= self::tag('h1', $headingOptions, $heading); + $output .= $content; + $output .= ''; + return $output; + } + + /** + * Generates a pager header. + * @param string $heading the heading text. + * @param string $subtext the subtext. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated pager header. + */ + public static function pageHeader($heading, $subtext, $htmlOptions = array()) + { + self::addCssClass('page-header', $htmlOptions); + $headerOptions = TbArray::popValue('headerOptions', $htmlOptions, array()); + $subtextOptions = TbArray::popValue('subtextOptions', $htmlOptions, array()); + $output = self::openTag('div', $htmlOptions); + $output .= self::openTag('h1', $headerOptions); + $output .= parent::encode($heading) . ' ' . self::tag('small', $subtextOptions, $subtext); + $output .= ''; + $output .= ''; + return $output; + } + + // Thumbnails + // http://twitter.github.io/bootstrap/2.3.2/components.html#thumbnails + // -------------------------------------------------- + + /** + * Generates a list of thumbnails. + * @param array $thumbnails the list configuration. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated thumbnails. + */ + public static function thumbnails(array $thumbnails, $htmlOptions = array()) + { + if (!empty($thumbnails)) { + self::addCssClass('thumbnails', $htmlOptions); + $defaultSpan = TbArray::popValue('span', $htmlOptions, 3); + $output = self::openTag('ul', $htmlOptions); + foreach ($thumbnails as $thumbnailOptions) { + if (isset($thumbnailOptions['visible']) && $thumbnailOptions['visible'] === false) { + continue; + } + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $thumbnailOptions, array()); + if (!empty($options)) { + $thumbnailOptions = TbArray::merge($options, $thumbnailOptions); + } + $thumbnailOptions['itemOptions']['span'] = TbArray::popValue('span', $thumbnailOptions, $defaultSpan); + $caption = TbArray::popValue('caption', $thumbnailOptions, ''); + $captionOptions = TbArray::popValue('captionOptions', $thumbnailOptions, array()); + self::addCssClass('caption', $captionOptions); + $label = TbArray::popValue('label', $thumbnailOptions); + $labelOptions = TbArray::popValue('labelOptions', $thumbnailOptions, array()); + if (!empty($label)) { + $caption = self::tag('h3', $labelOptions, $label) . $caption; + } + $content = !empty($caption) ? self::tag('div', $captionOptions, $caption) : ''; + $image = TbArray::popValue('image', $thumbnailOptions); + $imageOptions = TbArray::popValue('imageOptions', $thumbnailOptions, array()); + $imageAlt = TbArray::popValue('alt', $imageOptions, ''); + if (!empty($image)) { + $content = parent::image($image, $imageAlt, $imageOptions) . $content; + } + $url = TbArray::popValue('url', $thumbnailOptions, false); + $output .= $url !== false + ? self::thumbnailLink($content, $url, $thumbnailOptions) + : self::thumbnail($content, $thumbnailOptions); + } + $output .= ''; + return $output; + } else { + return ''; + } + } + + /** + * Generates a thumbnail. + * @param string $content the thumbnail content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated thumbnail. + */ + public static function thumbnail($content, $htmlOptions = array()) + { + $itemOptions = TbArray::popValue('itemOptions', $htmlOptions, array()); + self::addCssClass('thumbnail', $htmlOptions); + $output = self::openTag('li', $itemOptions); + $output .= self::tag('div', $htmlOptions, $content); + $output .= ''; + return $output; + } + + /** + * Generates a link thumbnail. + * @param string $content the thumbnail content. + * @param mixed $url the url that the thumbnail links to. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated thumbnail. + */ + public static function thumbnailLink($content, $url = '#', $htmlOptions = array()) + { + $itemOptions = TbArray::popValue('itemOptions', $htmlOptions, array()); + self::addCssClass('thumbnail', $htmlOptions); + $content = self::link($content, $url, $htmlOptions); + return self::tag('li', $itemOptions, $content); + } + + // Alerts + // http://twitter.github.io/bootstrap/2.3.2/components.html#alerts + // -------------------------------------------------- + + /** + * Generates an alert. + * @param string $color the color of the alert. + * @param string $message the message to display. + * @param array $htmlOptions additional HTML options. + * @return string the generated alert. + */ + public static function alert($color, $message, $htmlOptions = array()) + { + self::addCssClass('alert', $htmlOptions); + if (!empty($color)) { + self::addCssClass('alert-' . $color, $htmlOptions); + } + if (TbArray::popValue('in', $htmlOptions, true)) { + self::addCssClass('in', $htmlOptions); + } + if (TbArray::popValue('block', $htmlOptions, false)) { + self::addCssClass('alert-block', $htmlOptions); + } + if (TbArray::popValue('fade', $htmlOptions, true)) { + self::addCssClass('fade', $htmlOptions); + } + $closeText = TbArray::popValue('closeText', $htmlOptions, self::CLOSE_TEXT); + $closeOptions = TbArray::popValue('closeOptions', $htmlOptions, array()); + $closeOptions['dismiss'] = self::CLOSE_DISMISS_ALERT; + $output = self::openTag('div', $htmlOptions); + $output .= $closeText !== false ? self::closeLink($closeText, '#', $closeOptions) : ''; + $output .= $message; + $output .= ''; + return $output; + } + + /** + * Generates an alert block. + * @param string $color the color of the alert. + * @param string $message the message to display. + * @param array $htmlOptions additional HTML options. + * @return string the generated alert. + */ + public static function blockAlert($color, $message, $htmlOptions = array()) + { + $htmlOptions['block'] = true; + return self::alert($color, $message, $htmlOptions); + } + + // Progress bars + // http://twitter.github.io/bootstrap/2.3.2/components.html#progress + // -------------------------------------------------- + + /** + * Generates a progress bar. + * @param integer $width the progress in percent. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated progress bar. + */ + public static function progressBar($width = 0, $htmlOptions = array()) + { + self::addCssClass('progress', $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('progress-' . $color, $htmlOptions); + } + if (TbArray::popValue('striped', $htmlOptions, false)) { + self::addCssClass('progress-striped', $htmlOptions); + } + if (TbArray::popValue('animated', $htmlOptions, false)) { + self::addCssClass('active', $htmlOptions); + } + $barOptions = TbArray::popValue('barOptions', $htmlOptions, array()); + $content = TbArray::popValue('content', $htmlOptions); + if (!empty($content)) { + $barOptions['content'] = $content; + } + $content = self::bar($width, $barOptions); + return self::tag('div', $htmlOptions, $content); + } + + /** + * Generates a striped progress bar. + * @param integer $width the progress in percent. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated progress bar. + */ + public static function stripedProgressBar($width = 0, $htmlOptions = array()) + { + $htmlOptions['striped'] = true; + return self::progressBar($width, $htmlOptions); + } + + /** + * Generates an animated progress bar. + * @param integer $width the progress in percent. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated progress bar. + */ + public static function animatedProgressBar($width = 0, $htmlOptions = array()) + { + $htmlOptions['animated'] = true; + return self::stripedProgressBar($width, $htmlOptions); + } + + /** + * Generates a stacked progress bar. + * @param array $bars the bar configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated progress bar. + */ + public static function stackedProgressBar(array $bars, $htmlOptions = array()) + { + if (!empty($bars)) { + self::addCssClass('progress', $htmlOptions); + $output = self::openTag('div', $htmlOptions); + $totalWidth = 0; + foreach ($bars as $barOptions) { + if (isset($barOptions['visible']) && !$barOptions['visible']) { + continue; + } + $width = TbArray::popValue('width', $barOptions, 0); + $tmp = $totalWidth; + $totalWidth += $width; + if ($totalWidth > 100) { + $width = 100 - $tmp; + } + $output .= self::bar($width, $barOptions); + } + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates a progress bar. + * @param integer $width the progress in percent. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated bar. + */ + protected static function bar($width = 0, $htmlOptions = array()) + { + self::addCssClass('bar', $htmlOptions); + $color = TbArray::popValue('color', $htmlOptions); + if (!empty($color)) { + self::addCssClass('bar-' . $color, $htmlOptions); + } + if ($width < 0) { + $width = 0; + } + if ($width > 100) { + $width = 100; + } + if ($width > 0) { + $width .= '%'; + } + self::addCssStyle("width: {$width};", $htmlOptions); + $content = TbArray::popValue('content', $htmlOptions, ''); + return self::tag('div', $htmlOptions, $content); + } + + // Media objects + // http://twitter.github.io/bootstrap/2.3.2/components.html#media + // -------------------------------------------------- + + /** + * Generates a list of media objects. + * @param array $items item configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string generated list. + */ + public static function mediaList(array $items, $htmlOptions = array()) + { + if (!empty($items)) { + self::addCssClass('media-list', $htmlOptions); + $output = ''; + $output .= self::openTag('ul', $htmlOptions); + $output .= self::medias($items, 'li'); + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates multiple media objects. + * @param array $items item configurations. + * @param string $tag the item tag name. + * @return string generated objects. + */ + public static function medias(array $items, $tag = 'div') + { + if (!empty($items)) { + $output = ''; + foreach ($items as $itemOptions) { + if (isset($itemOptions['visible']) && $itemOptions['visible'] === false) { + continue; + } + // todo: consider removing the support for htmlOptions. + $options = TbArray::popValue('htmlOptions', $itemOptions, array()); + if (!empty($options)) { + $itemOptions = TbArray::merge($options, $itemOptions); + } + $image = TbArray::popValue('image', $itemOptions); + $heading = TbArray::popValue('heading', $itemOptions, ''); + $content = TbArray::popValue('content', $itemOptions, ''); + TbArray::defaultValue('tag', $tag, $itemOptions); + $output .= self::media($image, $heading, $content, $itemOptions); + } + return $output; + } + return ''; + } + + /** + * Generates a single media object. + * @param string $image the image url. + * @param string $heading the heading text. + * @param string $content the content text. + * @param array $htmlOptions additional HTML attributes. + * @return string the media object. + */ + public static function media($image, $heading, $content, $htmlOptions = array()) + { + $tag = TbArray::popValue('tag', $htmlOptions, 'div'); + self::addCssClass('media', $htmlOptions); + $linkOptions = TbArray::popValue('linkOptions', $htmlOptions, array()); + TbArray::defaultValue('pull', self::PULL_LEFT, $linkOptions); + $imageOptions = TbArray::popValue('imageOptions', $htmlOptions, array()); + self::addCssClass('media-object', $imageOptions); + $contentOptions = TbArray::popValue('contentOptions', $htmlOptions, array()); + self::addCssClass('media-body', $contentOptions); + $headingOptions = TbArray::popValue('headingOptions', $htmlOptions, array()); + self::addCssClass('media-heading', $headingOptions); + $items = TbArray::popValue('items', $htmlOptions); + + $output = self::openTag($tag, $htmlOptions); + $alt = TbArray::popValue('alt', $imageOptions, ''); + $href = TbArray::popValue('href', $linkOptions, '#'); + if (!empty($image)) { + $output .= self::link(parent::image($image, $alt, $imageOptions), $href, $linkOptions); + } + $output .= self::openTag('div', $contentOptions); + $output .= self::tag('h4', $headingOptions, $heading); + $output .= $content; + if (!empty($items)) { + $output .= self::medias($items); + } + $output .= ''; + $output .= self::closeTag($tag); + return $output; + } + + // Misc + // http://twitter.github.io/bootstrap/2.3.2/components.html#misc + // -------------------------------------------------- + + /** + * Generates a well element. + * @param string $content the well content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated well. + */ + public static function well($content, $htmlOptions = array()) + { + self::addCssClass('well', $htmlOptions); + $size = TbArray::popValue('size', $htmlOptions); + if (!empty($size)) { + self::addCssClass('well-' . $size, $htmlOptions); + } + return self::tag('div', $htmlOptions, $content); + } + + /** + * Generates a close link. + * @param string $label the link label text. + * @param mixed $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function closeLink($label = self::CLOSE_TEXT, $url = '#', $htmlOptions = array()) + { + $htmlOptions['href'] = $url; + return self::close('a', $label, $htmlOptions); + } + + /** + * Generates a close button. + * @param string $label the button label text. + * @param array $htmlOptions the HTML options for the button. + * @return string the generated button. + */ + public static function closeButton($label = self::CLOSE_TEXT, $htmlOptions = array()) + { + return self::close('button', $label, $htmlOptions); + } + + /** + * Generates a close element. + * @param string $tag the tag name. + * @param string $label the element label text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated element. + */ + protected static function close($tag, $label, $htmlOptions = array()) + { + self::addCssClass('close', $htmlOptions); + $dismiss = TbArray::popValue('dismiss', $htmlOptions); + if (!empty($dismiss)) { + $htmlOptions['data-dismiss'] = $dismiss; + } + $htmlOptions['type'] = 'button'; + return self::tag($tag, $htmlOptions, $label); + } + + /** + * Generates a collapse link. + * @param string $label the link label. + * @param string $target the CSS selector. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function collapseLink($label, $target, $htmlOptions = array()) + { + $htmlOptions['data-toggle'] = 'collapse'; + return self::link($label, $target, $htmlOptions); + } + + // + // JAVASCRIPT + // -------------------------------------------------- + + // Modals + // http://twitter.github.io/bootstrap/2.3.2/javascript.html#modals + // -------------------------------------------------- + + /** + * Generates a modal header. + * @param string $content the header content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated header. + */ + public static function modalHeader($content, $htmlOptions = array()) + { + self::addCssClass('modal-header', $htmlOptions); + $closeOptions = TbArray::popValue('closeOptions', $htmlOptions, array()); + $closeOptions['dismiss'] = 'modal'; + $headingOptions = TbArray::popValue('headingOptions', $htmlOptions, array()); + $closeLabel = TbArray::popValue('closeLabel', $htmlOptions, self::CLOSE_TEXT); + $closeButton = self::closeButton($closeLabel, $closeOptions); + $header = self::tag('h3', $headingOptions, $content); + return self::tag('div', $htmlOptions, $closeButton . $header); + } + + /** + * Generates a modal body. + * @param string $content the body content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated body. + */ + public static function modalBody($content, $htmlOptions = array()) + { + self::addCssClass('modal-body', $htmlOptions); + return self::tag('div', $htmlOptions, $content); + } + + /** + * Generates a modal footer. + * @param string $content the footer content. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated footer. + */ + public static function modalFooter($content, $htmlOptions = array()) + { + self::addCssClass('modal-footer', $htmlOptions); + return self::tag('div', $htmlOptions, $content); + } + + // Tooltips and Popovers + // http://twitter.github.io/bootstrap/2.3.2/javascript.html#tooltips + // http://twitter.github.io/bootstrap/2.3.2/javascript.html#popovers + // -------------------------------------------------- + + /** + * Generates a tooltip. + * @param string $label the tooltip link label text. + * @param mixed $url the link url. + * @param string $content the tooltip content text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated tooltip. + */ + public static function tooltip($label, $url, $content, $htmlOptions = array()) + { + $htmlOptions['rel'] = 'tooltip'; + return self::tooltipPopover($label, $url, $content, $htmlOptions); + } + + /** + * Generates a popover. + * @param string $label the popover link label text. + * @param string $title the popover title text. + * @param string $content the popover content text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated popover. + */ + public static function popover($label, $title, $content, $htmlOptions = array()) + { + $htmlOptions['rel'] = 'popover'; + $htmlOptions['data-content'] = $content; + $htmlOptions['data-toggle'] = 'popover'; + return self::tooltipPopover($label, '#', $title, $htmlOptions); + } + + /** + * Generates a base tooltip. + * @param string $label the tooltip link label text. + * @param mixed $url the link url. + * @param string $title the tooltip title text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated tooltip. + */ + protected static function tooltipPopover($label, $url, $title, $htmlOptions) + { + $htmlOptions['title'] = $title; + if (TbArray::popValue('animation', $htmlOptions)) { + $htmlOptions['data-animation'] = 'true'; + } + if (TbArray::popValue('html', $htmlOptions)) { + $htmlOptions['data-html'] = 'true'; + } + $selector = TbArray::popValue('selector', $htmlOptions); + if (!empty($selector)) { + $htmlOptions['data-selector'] = $selector; + } + $placement = TbArray::popValue('placement', $htmlOptions); + if (!empty($placement)) { + $htmlOptions['data-placement'] = $placement; + } + $trigger = TbArray::popValue('trigger', $htmlOptions); + if (!empty($trigger)) { + $htmlOptions['data-trigger'] = $trigger; + } + if (($delay = TbArray::popValue('delay', $htmlOptions)) !== null) { + $htmlOptions['data-delay'] = $delay; + } + return self::link($label, $url, $htmlOptions); + } + + // Carousel + // http://twitter.github.io/bootstrap/2.3.2/javascript.html#carousel + // -------------------------------------------------- + + /** + * Generates an image carousel. + * @param array $items the item configurations. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated carousel. + */ + public static function carousel(array $items, $htmlOptions = array()) + { + if (!empty($items)) { + $id = TbArray::getValue('id', $htmlOptions, parent::ID_PREFIX . parent::$count++); + TbArray::defaultValue('id', $id, $htmlOptions); + $selector = '#' . $id; + self::addCssClass('carousel', $htmlOptions); + if (TbArray::popValue('slide', $htmlOptions, true)) { + self::addCssClass('slide', $htmlOptions); + } + $interval = TbArray::popValue('data-interval', $htmlOptions); + if ($interval) { + $htmlOptions['data-interval'] = $interval; + } + $pause = TbArray::popValue('data-pause', $htmlOptions); + if ($pause) { + $htmlOptions['data-pause'] = $pause; + } + $indicatorOptions = TbArray::popValue('indicatorOptions', $htmlOptions, array()); + $innerOptions = TbArray::popValue('innerOptions', $htmlOptions, array()); + self::addCssClass('carousel-inner', $innerOptions); + $prevOptions = TbArray::popValue('prevOptions', $htmlOptions, array()); + $prevLabel = TbArray::popValue('label', $prevOptions, '‹'); + $nextOptions = TbArray::popValue('nextOptions', $htmlOptions, array()); + $nextLabel = TbArray::popValue('label', $nextOptions, '›'); + $hidePrevAndNext = TbArray::popValue('hidePrevAndNext', $htmlOptions, false); + $output = self::openTag('div', $htmlOptions); + $output .= self::carouselIndicators($selector, count($items), $indicatorOptions); + $output .= self::openTag('div', $innerOptions); + foreach ($items as $i => $itemOptions) { + if (isset($itemOptions['visible']) && $itemOptions['visible'] === false) { + continue; + } + if ($i === 0) { // first item should be active + self::addCssClass('active', $itemOptions); + } + $content = TbArray::popValue('content', $itemOptions, ''); + $image = TbArray::popValue('image', $itemOptions, ''); + $imageOptions = TbArray::popValue('imageOptions', $itemOptions, array()); + $imageAlt = TbArray::popValue('alt', $imageOptions, ''); + if (!empty($image)) { + $content = parent::image($image, $imageAlt, $imageOptions); + } + $label = TbArray::popValue('label', $itemOptions); + $caption = TbArray::popValue('caption', $itemOptions); + $output .= self::carouselItem($content, $label, $caption, $itemOptions); + } + $output .= ''; + if (!$hidePrevAndNext) { + $output .= self::carouselPrevLink($prevLabel, $selector, $prevOptions); + $output .= self::carouselNextLink($nextLabel, $selector, $nextOptions); + } + $output .= ''; + return $output; + } + return ''; + } + + /** + * Generates a carousel item. + * @param string $content the content. + * @param string $label the item label text. + * @param string $caption the item caption text. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated item. + */ + public static function carouselItem($content, $label, $caption, $htmlOptions = array()) + { + self::addCssClass('item', $htmlOptions); + $overlayOptions = TbArray::popValue('overlayOptions', $htmlOptions, array()); + self::addCssClass('carousel-caption', $overlayOptions); + $labelOptions = TbArray::popValue('labelOptions', $htmlOptions, array()); + $captionOptions = TbArray::popValue('captionOptions', $htmlOptions, array()); + $url = TbArray::popValue('url', $htmlOptions, false); + if ($url !== false) { + $content = self::link($content, $url); + } + $output = self::openTag('div', $htmlOptions); + $output .= $content; + if (isset($label) || isset($caption)) { + $output .= self::openTag('div', $overlayOptions); + if ($label) { + $output .= self::tag('h4', $labelOptions, $label); + } + if ($caption) { + $output .= self::tag('p', $captionOptions, $caption); + } + $output .= ''; + } + $output .= ''; + return $output; + } + + /** + * Generates a previous link for the carousel. + * @param string $label the link label text. + * @param mixed $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function carouselPrevLink($label, $url = '#', $htmlOptions = array()) + { + self::addCssClass('carousel-control left', $htmlOptions); + $htmlOptions['data-slide'] = 'prev'; + return self::link($label, $url, $htmlOptions); + } + + /** + * Generates a next link for the carousel. + * @param string $label the link label text. + * @param mixed $url the link url. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated link. + */ + public static function carouselNextLink($label, $url = '#', $htmlOptions = array()) + { + self::addCssClass('carousel-control right', $htmlOptions); + $htmlOptions['data-slide'] = 'next'; + return self::link($label, $url, $htmlOptions); + } + + /** + * Generates an indicator for the carousel. + * @param string $target the CSS selector for the target element. + * @param integer $numSlides the number of slides. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated indicators. + */ + public static function carouselIndicators($target, $numSlides, $htmlOptions = array()) + { + self::addCssClass('carousel-indicators', $htmlOptions); + $output = self::openTag('ol', $htmlOptions); + for ($i = 0; $i < $numSlides; $i++) { + $itemOptions = array('data-target' => $target, 'data-slide-to' => $i); + if ($i === 0) { + $itemOptions['class'] = 'active'; + } + $output .= self::tag('li', $itemOptions, '', true); + } + $output .= ''; + return $output; + } + + // UTILITIES + // -------------------------------------------------- + + /** + * Appends new class names to the given options.. + * @param mixed $className the class(es) to append. + * @param array $htmlOptions the options. + * @return array the options. + */ + public static function addCssClass($className, &$htmlOptions) + { + // Always operate on arrays + if (is_string($className)) { + $className = explode(' ', $className); + } + if (isset($htmlOptions['class'])) { + $classes = array_filter(explode(' ', $htmlOptions['class'])); + foreach ($className as $class) { + $class = trim($class); + // Don't add the class if it already exists + if (array_search($class, $classes) === false) { + $classes[] = $class; + } + } + $className = $classes; + } + $htmlOptions['class'] = implode(' ', $className); + } + + /** + * Appends a CSS style string to the given options. + * @param string $style the CSS style string. + * @param array $htmlOptions the options. + * @return array the options. + */ + public static function addCssStyle($style, &$htmlOptions) + { + if (is_array($style)) { + $style = implode('; ', $style); + } + $style = rtrim($style, ';'); + $htmlOptions['style'] = isset($htmlOptions['style']) + ? rtrim($htmlOptions['style'], ';') . '; ' . $style + : $style; + } + + /** + * Adds the grid span class to the given options is applicable. + * @param array $htmlOptions the HTML attributes. + */ + protected static function addSpanClass(&$htmlOptions) + { + $span = TbArray::popValue('span', $htmlOptions); + if (!empty($span)) { + self::addCssClass('span' . $span, $htmlOptions); + } + } + + /** + * Adds the pull class to the given options is applicable. + * @param array $htmlOptions the HTML attributes. + */ + protected static function addPullClass(&$htmlOptions) + { + $pull = TbArray::popValue('pull', $htmlOptions); + if (!empty($pull)) { + self::addCssClass('pull-' . $pull, $htmlOptions); + } + } + + /** + * Adds the text align class to the given options if applicable. + * @param array $htmlOptions the HTML attributes. + */ + protected static function addTextAlignClass(&$htmlOptions) + { + $align = TbArray::popValue('textAlign', $htmlOptions); + if (!empty($align)) { + self::addCssClass('text-' . $align, $htmlOptions); + } + } +} diff --git a/www/protected/extensions/bootstrap/package.json b/www/protected/extensions/bootstrap/package.json new file mode 100644 index 0000000..1e644cf --- /dev/null +++ b/www/protected/extensions/bootstrap/package.json @@ -0,0 +1,28 @@ +{ + "name": "yiistrap", + "version": "1.0.0", + "author": "Christoffer Niska ", + "description": "Yiistrap, Twitter Bootstrap for Yii.", + "contributors": [ + { + "name": "Christoffer Niska", + "email": "christoffer.niska@gmail.com", + "homepage": "http://www.cniska.net/" + }, + { + "name": "Antonio Ramirez", + "email": "ramirez.cobos@gmail.com", + "homepage": "http://www.ramirezcobos.com/" + } + ], + "keywords": [ + "yii", + "yiistrap", + "bootstrap" + ], + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-less": "~0.6.1", + "grunt-contrib-watch": "~0.4.4" + } +} diff --git a/www/protected/extensions/bootstrap/tests/_bootstrap.php b/www/protected/extensions/bootstrap/tests/_bootstrap.php new file mode 100644 index 0000000..a2a1e9b --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/_bootstrap.php @@ -0,0 +1,14 @@ +assertTrue(strpos($node->text(), $text) !== false); + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param $pattern $text + */ + public function seeNodePattern($node, $pattern) + { + $this->assertEquals(1, preg_match($pattern, $node->html())); + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + */ + public function seeNodeEmpty($node) + { + $this->assertEquals('', $node->text()); + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + */ + public function seeNodeCssClass($node, $cssClass) + { + if (is_string($cssClass)) { + $cssClass = explode(' ', $cssClass); + } + foreach ($cssClass as $className) { + $this->assertTrue(in_array($className, explode(' ', $node->attr('class')))); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + */ + public function dontSeeNodeCssClass($node, $cssClass) + { + if (is_string($cssClass)) { + $cssClass = explode(' ', $cssClass); + } + foreach ($cssClass as $className) { + $this->assertFalse(in_array($className, explode(' ', $node->attr('class')))); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + */ + public function seeNodeCssStyle($node, $cssStyle) + { + if (is_string($cssStyle)) { + $cssStyle = explode(';', rtrim($cssStyle, ';')); + } + $cssStyle = $this->normalizeCssStyle($cssStyle); + foreach ($cssStyle as $style) { + $this->assertTrue(strpos($node->attr('style'), $style) !== false); + } + } + + /** + * @param array $cssStyle + * @return array + */ + protected function normalizeCssStyle(array $cssStyle) + { + array_walk( + $cssStyle, + function (&$value) { + $value = trim($value); + } + ); + return $cssStyle; + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + */ + public function dontSeeNodeCssStyle($node, $cssStyle) + { + if (is_string($cssStyle)) { + $cssStyle = explode(';', rtrim($cssStyle, ';')); + } + $cssStyle = $this->normalizeCssStyle($cssStyle); + foreach ($cssStyle as $style) { + $this->assertFalse(strpos($node->attr('style'), $style)); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $name + * @param string $value + */ + public function seeNodeAttribute($node, $name, $value = null) + { + $attr = $node->attr($name); + $this->assertTrue($attr !== null); + if ($value !== null) { + $this->assertEquals($value, $attr); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $name + */ + public function dontSeeNodeAttribute($node, $name) + { + $this->assertEquals('', $node->attr($name)); + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + */ + public function seeNodeAttributes($node, array $attributes) + { + foreach ($attributes as $name => $value) { + $this->seeNodeAttribute($node, $name, $value); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + */ + public function dontSeeNodeAttributes($node, array $attributes) + { + foreach ($attributes as $name) { + $this->dontSeeNodeAttribute($node, $name); + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + */ + public function seeNodeChildren($node, array $elements) + { + /** @var \DomElement $child */ + foreach ($node->children() as $i => $child) { + if (isset($elements[$i])) { + $this->assertTrue($this->nodeMatchesCssSelector($child, $elements[$i])); + } + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + */ + public function dontSeeNodeChildren($node, array $elements) + { + /** @var \DomElement $child */ + foreach ($node->children() as $i => $child) { + if (isset($elements[$i])) { + $this->assertFalse($this->nodeMatchesCssSelector($child, $elements[$i])); + } + } + } + + /** + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param integer $amount + */ + public function seeNodeNumChildren($node, $amount, $filter = null) + { + $count = $filter !== null ? $node->filter($filter)->count() : $node->children()->count(); + $this->assertEquals($amount, $count); + } + + /** + * @param \DomElement $node + * @param string $selector + * @return boolean + */ + protected function nodeMatchesCssSelector($node, $selector) + { + if ($node->parentNode === null) { + return false; + } + $crawler = $this->createNode($node->parentNode); + return count($crawler->filter($selector)) > 0; + } + + /** + * @param mixed $content + * @param string $filter + * @return \Symfony\Component\DomCrawler\Crawler + */ + public function createNode($content, $filter = null) + { + $crawler = new \Symfony\Component\DomCrawler\Crawler($content); + if ($filter !== null) { + $node = $crawler->filter($filter); + $this->assertNotEquals(null, $node); + return $node; + } + return $crawler; + } +} diff --git a/www/protected/extensions/bootstrap/tests/_helpers/TestHelper.php b/www/protected/extensions/bootstrap/tests/_helpers/TestHelper.php new file mode 100644 index 0000000..37737cd --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/_helpers/TestHelper.php @@ -0,0 +1,8 @@ +scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeText', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $text + * @see Codeception\Module\CodeHelper::seeNodeText() + * @return \Codeception\Maybe + */ + public function seeNodeText($node, $text) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeText', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param $pattern $text + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodePattern() + * @return \Codeception\Maybe + */ + public function canSeeNodePattern($node, $pattern) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodePattern', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param $pattern $text + * @see Codeception\Module\CodeHelper::seeNodePattern() + * @return \Codeception\Maybe + */ + public function seeNodePattern($node, $pattern) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodePattern', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeEmpty() + * @return \Codeception\Maybe + */ + public function canSeeNodeEmpty($node) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeEmpty', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @see Codeception\Module\CodeHelper::seeNodeEmpty() + * @return \Codeception\Maybe + */ + public function seeNodeEmpty($node) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeEmpty', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeCssClass() + * @return \Codeception\Maybe + */ + public function canSeeNodeCssClass($node, $cssClass) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeCssClass', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + * @see Codeception\Module\CodeHelper::seeNodeCssClass() + * @return \Codeception\Maybe + */ + public function seeNodeCssClass($node, $cssClass) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeCssClass', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::dontSeeNodeCssClass() + * @return \Codeception\Maybe + */ + public function cantSeeNodeCssClass($node, $cssClass) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('dontSeeNodeCssClass', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param mixed $cssClass + * @see Codeception\Module\CodeHelper::dontSeeNodeCssClass() + * @return \Codeception\Maybe + */ + public function dontSeeNodeCssClass($node, $cssClass) { + $this->scenario->addStep(new \Codeception\Step\Assertion('dontSeeNodeCssClass', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeCssStyle() + * @return \Codeception\Maybe + */ + public function canSeeNodeCssStyle($node, $cssStyle) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeCssStyle', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + * @see Codeception\Module\CodeHelper::seeNodeCssStyle() + * @return \Codeception\Maybe + */ + public function seeNodeCssStyle($node, $cssStyle) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeCssStyle', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::dontSeeNodeCssStyle() + * @return \Codeception\Maybe + */ + public function cantSeeNodeCssStyle($node, $cssStyle) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('dontSeeNodeCssStyle', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $cssStyle + * @see Codeception\Module\CodeHelper::dontSeeNodeCssStyle() + * @return \Codeception\Maybe + */ + public function dontSeeNodeCssStyle($node, $cssStyle) { + $this->scenario->addStep(new \Codeception\Step\Assertion('dontSeeNodeCssStyle', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $name + * @param string $value + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeAttribute() + * @return \Codeception\Maybe + */ + public function canSeeNodeAttribute($node, $name, $value = null) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeAttribute', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param string $name + * @param string $value + * @see Codeception\Module\CodeHelper::seeNodeAttribute() + * @return \Codeception\Maybe + */ + public function seeNodeAttribute($node, $name, $value = null) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeAttribute', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $name + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::dontSeeNodeAttribute() + * @return \Codeception\Maybe + */ + public function cantSeeNodeAttribute($node, $name) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('dontSeeNodeAttribute', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $name + * @see Codeception\Module\CodeHelper::dontSeeNodeAttribute() + * @return \Codeception\Maybe + */ + public function dontSeeNodeAttribute($node, $name) { + $this->scenario->addStep(new \Codeception\Step\Assertion('dontSeeNodeAttribute', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeAttributes() + * @return \Codeception\Maybe + */ + public function canSeeNodeAttributes($node, $attributes) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeAttributes', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + * @see Codeception\Module\CodeHelper::seeNodeAttributes() + * @return \Codeception\Maybe + */ + public function seeNodeAttributes($node, $attributes) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeAttributes', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::dontSeeNodeAttributes() + * @return \Codeception\Maybe + */ + public function cantSeeNodeAttributes($node, $attributes) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('dontSeeNodeAttributes', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $attributes + * @see Codeception\Module\CodeHelper::dontSeeNodeAttributes() + * @return \Codeception\Maybe + */ + public function dontSeeNodeAttributes($node, $attributes) { + $this->scenario->addStep(new \Codeception\Step\Assertion('dontSeeNodeAttributes', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeChildren() + * @return \Codeception\Maybe + */ + public function canSeeNodeChildren($node, $elements) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + * @see Codeception\Module\CodeHelper::seeNodeChildren() + * @return \Codeception\Maybe + */ + public function seeNodeChildren($node, $elements) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::dontSeeNodeChildren() + * @return \Codeception\Maybe + */ + public function cantSeeNodeChildren($node, $elements) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('dontSeeNodeChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param array $elements + * @see Codeception\Module\CodeHelper::dontSeeNodeChildren() + * @return \Codeception\Maybe + */ + public function dontSeeNodeChildren($node, $elements) { + $this->scenario->addStep(new \Codeception\Step\Assertion('dontSeeNodeChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param integer $amount + * Conditional Assertion: Test won't be stopped on fail + * @see Codeception\Module\CodeHelper::seeNodeNumChildren() + * @return \Codeception\Maybe + */ + public function canSeeNodeNumChildren($node, $amount) { + $this->scenario->addStep(new \Codeception\Step\ConditionalAssertion('seeNodeNumChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param \Symfony\Component\DomCrawler\Crawler $node + * @param integer $amount + * @see Codeception\Module\CodeHelper::seeNodeNumChildren() + * @return \Codeception\Maybe + */ + public function seeNodeNumChildren($node, $amount) { + $this->scenario->addStep(new \Codeception\Step\Assertion('seeNodeNumChildren', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } + + + /** + * This method is generated. + * Documentation taken from corresponding module. + * ---------------------------------------------- + * + * @param mixed $content + * @param string $filter + * @return \Symfony\Component\DomCrawler\Crawler + * @see Codeception\Module\CodeHelper::createNode() + * @return \Codeception\Maybe + */ + public function createNode($content, $filter = null) { + $this->scenario->addStep(new \Codeception\Step\Action('createNode', func_get_args())); + if ($this->scenario->running()) { + $result = $this->scenario->runStep(); + return new Maybe($result); + } + return new Maybe(); + } +} + diff --git a/www/protected/extensions/bootstrap/tests/unit/TbArrayTest.php b/www/protected/extensions/bootstrap/tests/unit/TbArrayTest.php new file mode 100644 index 0000000..0e08d46 --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/unit/TbArrayTest.php @@ -0,0 +1,93 @@ + 'value'); + $this->assertEquals('value', TbArray::getValue('key', $array)); + } + + public function testPopValue() + { + $array = array('key' => 'value'); + $this->assertEquals('value', TbArray::popValue('key', $array)); + $this->assertArrayNotHasKey('key', $array); + } + + public function testDefaultValue() + { + $array = array(); + TbArray::defaultValue('key', 'default', $array); + $this->assertEquals('default', TbArray::getValue('key', $array)); + TbArray::defaultValue('key', 'value', $array); + $this->assertEquals('default', TbArray::getValue('key', $array)); + } + + public function testDefaultValues() + { + $array = array('my' => 'value'); + TbArray::defaultValues(array('these' => 'are', 'my' => 'defaults'), $array); + $this->assertEquals('are', TbArray::getValue('these', $array)); + $this->assertEquals('value', TbArray::getValue('my', $array)); + } + + public function testRemoveValue() + { + $array = array('key' => 'value'); + TbArray::removeValue('key', $array); + $this->assertArrayNotHasKey('key', $array); + } + + public function testRemoveValues() + { + $array = array('these' => 'are', 'my' => 'values'); + TbArray::removeValues(array('these', 'my'), $array); + $this->assertArrayNotHasKey('these', $array); + $this->assertArrayNotHasKey('my', $array); + } + + public function testCopyValues() + { + $a = array('key' => 'value'); + $b = array(); + $array = TbArray::copyValues(array('key'), $a, $b); + $this->assertEquals($a, $array); + $a = array('key' => 'value'); + $b = array('key' => 'other'); + $array = TbArray::copyValues(array('key'), $a, $b, true); + $this->assertEquals($a, $array); + } + + public function testMoveValues() + { + $a = array('key' => 'value'); + $b = array(); + $array = TbArray::moveValues(array('key'), $a, $b); + $this->assertArrayNotHasKey('key', $a); + $this->assertEquals('value', TbArray::getValue('key', $array)); + $a = array('key' => 'value'); + $b = array('key' => 'other'); + $array = TbArray::moveValues(array('key'), $a, $b, true); + $this->assertEquals('value', TbArray::getValue('key', $array)); + } + + public function testMerge() + { + $a = array('this' => 'is', 'array' => 'a'); + $b = array('is' => 'this', 'b' => 'array'); + $array = TbArray::merge($a, $b); + $this->assertEquals('is', TbArray::getValue('this', $array)); + $this->assertEquals('a', TbArray::getValue('array', $array)); + $this->assertEquals('this', TbArray::getValue('is', $array)); + $this->assertEquals('array', TbArray::getValue('b', $array)); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/tests/unit/TbHtmlTest.php b/www/protected/extensions/bootstrap/tests/unit/TbHtmlTest.php new file mode 100644 index 0000000..fd1527a --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/unit/TbHtmlTest.php @@ -0,0 +1,3934 @@ +mockApplication(); + } + + public function testLead() + { + $I = $this->codeGuy; + $html = TbHtml::lead('Lead text'); + $p = $I->createNode($html, 'p.lead'); + $I->seeNodeText($p, 'Lead text'); + } + + public function testSmall() + { + $I = $this->codeGuy; + $html = TbHtml::small('Small text'); + $small = $I->createNode($html, 'small'); + $I->seeNodeText($small, 'Small text'); + } + + public function testBold() + { + $I = $this->codeGuy; + $html = TbHtml::b('Bold text'); + $strong = $I->createNode($html, 'strong'); + $I->seeNodeText($strong, 'Bold text'); + } + + public function testItalic() + { + $I = $this->codeGuy; + $html = TbHtml::i('Italic text'); + $em = $I->createNode($html, 'em'); + $I->seeNodeText($em, 'Italic text'); + } + + public function testEmphasize() + { + $I = $this->codeGuy; + + $html = TbHtml::em( + 'Warning text', + array( + 'color' => TbHtml::TEXT_COLOR_WARNING, + ) + ); + $span = $I->createNode($html, 'p.text-warning'); + $I->seeNodeText($span, 'Warning text'); + + $html = TbHtml::em( + 'Success text', + array( + 'color' => TbHtml::TEXT_COLOR_SUCCESS, + ), + 'span' + ); + $span = $I->createNode($html, 'span.text-success'); + $I->seeNodeText($span, 'Success text'); + } + + public function testMuted() + { + $I = $this->codeGuy; + $html = TbHtml::muted('Muted text'); + $p = $I->createNode($html, 'p.muted'); + $I->seeNodeText($p, 'Muted text'); + } + + public function testMutedSpan() + { + $I = $this->codeGuy; + $html = TbHtml::mutedSpan('Muted text'); + $span = $I->createNode($html, 'span.muted'); + $I->seeNodeText($span, 'Muted text'); + } + + public function testAbbreviation() + { + $I = $this->codeGuy; + $html = TbHtml::abbr('Abbreviation', 'Word'); + $abbr = $I->createNode($html, 'abbr'); + $I->seeNodeAttribute($abbr, 'title', 'Word'); + $I->seeNodeText($abbr, 'Abbreviation'); + } + + public function testSmallAbbreviation() + { + $I = $this->codeGuy; + $html = TbHtml::smallAbbr('Abbreviation', 'Word'); + $abbr = $I->createNode($html, 'abbr'); + $I->seeNodeAttribute($abbr, 'title', 'Word'); + $I->seeNodeCssClass($abbr, 'initialism'); + $I->seeNodeText($abbr, 'Abbreviation'); + } + + public function testAddress() + { + $I = $this->codeGuy; + $html = TbHtml::address('Address text'); + $addr = $I->createNode($html, 'address'); + $I->seeNodeText($addr, 'Address text'); + } + + public function testQuote() + { + $I = $this->codeGuy; + $html = TbHtml::quote( + 'Quote text', + array( + 'paragraphOptions' => array('class' => 'paragraph'), + 'source' => 'Source text', + 'sourceOptions' => array('class' => 'source'), + 'cite' => 'Cited text', + 'citeOptions' => array('class' => 'cite'), + ) + ); + $blockquote = $I->createNode($html, 'blockquote'); + $I->seeNodeChildren($blockquote, array('p', 'small')); + $p = $blockquote->filter('p'); + $I->seeNodeCssClass($p, 'paragraph'); + $I->seeNodeText($p, 'Quote text'); + $small = $blockquote->filter('blockquote > small'); + $I->seeNodeCssClass($small, 'source'); + $I->seeNodeText($small, 'Source text'); + $cite = $small->filter('small > cite'); + $I->seeNodeCssClass($cite, 'cite'); + $I->seeNodeText($cite, 'Cited text'); + // todo: consider writing a test including the pull-right quote as well. + } + + public function testHelp() + { + $I = $this->codeGuy; + $html = TbHtml::help('Help text'); + $span = $I->createNode($html, 'span.help-inline'); + $I->seeNodeText($span, 'Help text'); + } + + public function testHelpBlock() + { + $I = $this->codeGuy; + $html = TbHtml::helpBlock('Help text'); + $p = $I->createNode($html, 'p.help-block'); + $I->seeNodeText($p, 'Help text'); + } + + public function testCode() + { + $I = $this->codeGuy; + $html = TbHtml::code('Source code'); + $code = $I->createNode($html, 'code'); + $I->seeNodeText($code, 'Source code'); + } + + public function testCodeBlock() + { + $I = $this->codeGuy; + $html = TbHtml::codeBlock('Source code'); + $pre = $I->createNode($html, 'pre'); + $I->seeNodeText($pre, 'Source code'); + } + + public function testTag() + { + $I = $this->codeGuy; + $html = TbHtml::tag( + 'div', + array( + 'textAlign' => TbHtml::TEXT_ALIGN_RIGHT, + 'pull' => TbHtml::PULL_RIGHT, + 'span' => 3, + ), + 'Content' + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'pull-right span3 text-right'); + } + + public function testOpenTag() + { + $I = $this->codeGuy; + $html = TbHtml::openTag( + 'p', + array( + 'class' => 'tag', + ) + ); + $p = $I->createNode($html, 'p'); + $I->seeNodeCssClass($p, 'tag'); + } + + public function testForm() + { + $I = $this->codeGuy; + $html = TbHtml::formTb( + TbHtml::FORM_LAYOUT_VERTICAL, + '#', + 'post', + array( + 'class' => 'form', + ) + ); + $form = $I->createNode($html, 'form.form-vertical'); + $I->seeNodeCssClass($form, 'form'); + $I->seeNodeAttributes( + $form, + array( + 'action' => '#', + 'method' => 'post' + ) + ); + } + + public function testBeginForm() + { + $I = $this->codeGuy; + $html = TbHtml::beginFormTb(TbHtml::FORM_LAYOUT_VERTICAL, '#'); + $form = $I->createNode($html, 'form'); + $I->seeNodeCssClass($form, 'form-vertical'); + } + + public function testStatefulForm() + { + $I = $this->codeGuy; + $html = TbHtml::statefulFormTb(TbHtml::FORM_LAYOUT_VERTICAL, '#'); + $body = $I->createNode($html); + $form = $body->filter('form'); + $I->seeNodeCssClass($form, 'form-vertical'); + $div = $body->filter('div'); + $I->seeNodeCssStyle($div, 'display: none'); + $input = $div->filter('input[type=hidden]'); + $I->seeNodeAttributes( + $input, + array( + 'name' => 'YII_PAGE_STATE', + 'value' => '', + ) + ); + } + + public function testTextField() + { + $I = $this->codeGuy; + + $html = TbHtml::textField( + 'text', + 'text', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=text]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'text', + 'name' => 'text', + 'value' => 'text', + ) + ); + + $html = TbHtml::textField( + 'text', + 'text', + array( + 'prepend' => 'Prepend text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-prepend'); + $I->seeNodeChildren($div, array('span', 'input')); + $span = $div->filter('span.add-on'); + $I->seeNodeText($span, 'Prepend text'); + + $html = TbHtml::textField( + 'text', + 'text', + array( + 'append' => 'Append text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-append'); + $I->seeNodeChildren($div, array('input', 'span')); + $span = $div->filter('span.add-on'); + $I->seeNodeText($span, 'Append text'); + + $html = TbHtml::textField( + 'text', + 'text', + array( + 'prepend' => 'Prepend text', + 'append' => 'Append text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-prepend input-append'); + $I->seeNodeChildren($div, array('span', 'input', 'span')); + + $html = TbHtml::textField( + 'text', + 'text', + array( + 'block' => true, + ) + ); + $input = $I->createNode($html, 'input'); + $I->seeNodeCssClass($input, 'input-block-level'); + } + + public function testPasswordField() + { + $I = $this->codeGuy; + $html = TbHtml::passwordField( + 'password', + 'secret', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=password]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'password', + 'name' => 'password', + 'value' => 'secret', + ) + ); + } + + public function testUrlField() + { + $I = $this->codeGuy; + $html = TbHtml::urlField( + 'url', + 'http://www.getyiistrap.com', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=url]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'url', + 'name' => 'url', + 'value' => 'http://www.getyiistrap.com', + ) + ); + } + + public function testEmailField() + { + $I = $this->codeGuy; + $html = TbHtml::emailField( + 'email', + 'christoffer.niska@gmail.com', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=email]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'email', + 'name' => 'email', + 'value' => 'christoffer.niska@gmail.com', + ) + ); + } + + public function testNumberField() + { + $I = $this->codeGuy; + $html = TbHtml::numberField( + 'number', + 42, + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=number]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'number', + 'name' => 'number', + 'value' => '42', + ) + ); + } + + public function testRangeField() + { + $I = $this->codeGuy; + $html = TbHtml::rangeField( + 'range', + 3.33, + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=range]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'range', + 'name' => 'range', + 'value' => '3.33', + ) + ); + } + + public function testDateField() + { + $I = $this->codeGuy; + $html = TbHtml::dateField( + 'date', + '2013-08-28', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=date]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'date', + 'name' => 'date', + 'value' => '2013-08-28', + ) + ); + } + + public function testFileField() + { + $I = $this->codeGuy; + $html = TbHtml::fileField( + 'file', + '', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=file]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'file', + 'name' => 'file', + 'value' => '', + ) + ); + } + + public function testTextArea() + { + $I = $this->codeGuy; + $html = TbHtml::textArea( + 'textarea', + 'Textarea text', + array( + 'class' => 'textarea', + ) + ); + $textarea = $I->createNode($html, 'textarea'); + $I->seeNodeAttributes( + $textarea, + array( + 'class' => 'textarea', + 'id' => 'textarea', + 'name' => 'textarea', + ) + ); + $I->seeNodeText($textarea, 'Textarea text'); + } + + public function testRadioButton() + { + $I = $this->codeGuy; + + $html = TbHtml::radioButton( + 'radio', + false, + array( + 'class' => 'input', + 'label' => 'Label text', + ) + ); + $label = $I->createNode($html, 'label'); + $I->seeNodeCssClass($label, 'radio'); + $I->seeNodePattern($label, '/> Label text$/'); + $input = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'radio', + 'name' => 'radio', + 'value' => '1', + ) + ); + $I->dontSeeNodeAttribute($input, 'checked'); + + $html = TbHtml::radioButton('radio', true); + $input = $I->createNode($html, 'input[type=radio]'); + $I->seeNodeAttribute($input, 'checked', 'checked'); + } + + public function testCheckBox() + { + $I = $this->codeGuy; + $html = TbHtml::checkBox( + 'checkbox', + false, + array( + 'class' => 'input', + 'label' => 'Label text', + ) + ); + $label = $I->createNode($html, 'label'); + $I->seeNodeCssClass($label, 'checkbox'); + $I->seeNodePattern($label, '/> Label text$/'); + $input = $label->filter('input[type=checkbox]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'checkbox', + 'name' => 'checkbox', + 'value' => '1', + ) + ); + $I->dontSeeNodeAttribute($input, 'checked'); + + $html = TbHtml::checkBox('checkbox', true); + $input = $I->createNode($html, 'input[type=checkbox]'); + $I->seeNodeAttribute($input, 'checked', 'checked'); + } + + public function testDropDownList() + { + $I = $this->codeGuy; + $html = TbHtml::dropDownList( + 'dropdown', + null, + array('1', '2', '3', '4', '5'), + array( + 'class' => 'list', + 'empty' => 'Empty text', + 'size' => TbHtml::INPUT_SIZE_LARGE, + 'textAlign' => TbHtml::TEXT_ALIGN_CENTER, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeCssClass($select, 'input-large text-center list'); + $I->dontSeeNodeAttribute($select, 'size'); + } + + public function testListBox() + { + $I = $this->codeGuy; + + $html = TbHtml::listBox( + 'listbox', + null, + array('1', '2', '3', '4', '5'), + array( + 'class' => 'list', + 'empty' => 'Empty text', + 'size' => TbHtml::INPUT_SIZE_LARGE, + 'textAlign' => TbHtml::TEXT_ALIGN_CENTER, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeCssClass($select, 'input-large text-center list'); + $I->seeNodeAttributes( + $select, + array( + 'name' => 'listbox', + 'id' => 'listbox', + 'size' => 4, + ) + ); + + $html = TbHtml::listBox( + 'listbox', + null, + array('1', '2', '3', '4', '5'), + array( + 'multiple' => true, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeAttribute($select, 'name', 'listbox[]'); + } + + public function testRadioButtonList() + { + $I = $this->codeGuy; + $html = TbHtml::radioButtonList( + 'radioList', + null, + array('Option 1', 'Option 2', 'Option 3'), + array( + 'separator' => '
', + 'container' => 'div', + 'containerOptions' => array('class' => 'container'), + ) + ); + $container = $I->createNode($html, 'div.container'); + $I->seeNodeChildren($container, array('label.radio', 'br', 'label.radio', 'br', 'label.radio')); + $label = $container->filter('label')->first(); + $I->seeNodePattern($label, '/> Option 1$/'); + $input = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'radioList_0', + 'name' => 'radioList', + 'value' => '0', + ) + ); + } + + public function testInlineRadioButtonList() + { + $I = $this->codeGuy; + $html = TbHtml::inlineRadioButtonList( + 'radioList', + null, + array('Option 1', 'Option 2', 'Option 3') + ); + $span = $I->createNode($html, 'span'); + $I->seeNodeNumChildren($span, 3); + $I->seeNodeChildren($span, array('label.radio.inline', 'label.radio.inline', 'label.radio.inline')); + } + + public function testCheckboxList() + { + $I = $this->codeGuy; + + $html = TbHtml::checkBoxList( + 'checkboxList', + null, + array('Option 1', 'Option 2', 'Option 3'), + array( + 'separator' => '
', + 'container' => 'div', + 'containerOptions' => array('class' => 'container'), + ) + ); + $container = $I->createNode($html, 'div.container'); + $I->seeNodeChildren($container, array('label.checkbox', 'br', 'label.checkbox', 'br', 'label.checkbox')); + $label = $container->filter('label')->first(); + $I->seeNodePattern($label, '/> Option 1$/'); + $input = $label->filter('input[type=checkbox]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'checkboxList_0', + 'name' => 'checkboxList[]', + 'value' => '0', + ) + ); + + $html = TbHtml::checkBoxList( + 'checkboxList', + null, + array('Option 1', 'Option 2', 'Option 3'), + array( + 'checkAll' => true, + ) + ); + $span = $I->createNode($html, 'span'); + $I->seeNodeChildren( + $span, + array('input[type=checkbox]', 'label.checkbox', 'label.checkbox', 'label.checkbox', 'label.checkbox') + ); + $label = $span->filter('label')->first(); + $input = $label->filter('input'); + $I->seeNodeAttribute($input, 'name', 'checkboxList_all'); + + $html = TbHtml::checkBoxList( + 'checkboxList', + null, + array('Option 1', 'Option 2', 'Option 3'), + array( + 'checkAll' => true, + 'checkAllLast' => true, + ) + ); + $span = $I->createNode($html, 'span'); + $I->seeNodeChildren( + $span, + array('label.checkbox', 'label.checkbox', 'label.checkbox', 'label.checkbox', 'input[type=checkbox]') + ); + $label = $span->filter('label')->last(); + $input = $label->filter('input'); + $I->seeNodeAttribute($input, 'name', 'checkboxList_all'); + } + + public function testInlineCheckBoxList() + { + $I = $this->codeGuy; + $html = TbHtml::inlineCheckBoxList( + 'checkboxList', + null, + array('Option 1', 'Option 2', 'Option 3') + ); + $span = $I->createNode($html, 'span'); + $I->seeNodeNumChildren($span, 3); + $I->seeNodeChildren( + $span, + array('label.checkbox.inline', 'label.checkbox.inline', 'label.checkbox.inline') + ); + } + + public function testUneditableField() + { + $I = $this->codeGuy; + $html = TbHtml::uneditableField( + 'Uneditable text', + array( + 'class' => 'span', + ) + ); + $span = $I->createNode($html, 'span.uneditable-input'); + $I->seeNodeCssClass($span, 'span'); + $I->seeNodeText($span, 'Uneditable text'); + } + + public function testSearchQueryField() + { + $I = $this->codeGuy; + $html = TbHtml::searchQueryField( + 'search', + 'Search query', + array( + 'class' => 'input', + ) + ); + $input = $I->createNode($html, 'input[type=text].search-query'); + $I->seeNodeCssClass($input, 'input'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'search', + 'name' => 'search', + 'value' => 'Search query', + ) + ); + } + + public function testTextFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::textFieldControlGroup('text', 'text'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=text]')); + } + + public function testPasswordFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::passwordFieldControlGroup('password', 'secret'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=password]')); + } + + public function testUrlFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::urlFieldControlGroup('url', 'url'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=url]')); + } + + public function testEmailFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::emailFieldControlGroup('email', 'email'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=email]')); + } + + public function testNumberFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::numberFieldControlGroup('number', 'number'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=number]')); + } + + public function testRangeFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::rangeFieldControlGroup('range', 'range'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=range]')); + } + + public function testDateFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::dateFieldControlGroup('date', 'date'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=date]')); + } + + public function testFileFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::fileFieldControlGroup('file', 'file'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=file]')); + } + + public function testTextAreaControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::textAreaControlGroup('textarea', 'Textarea text'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('textarea')); + } + + public function testRadioButtonControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::radioButtonControlGroup( + 'radio', + false, + array( + 'label' => 'Label text', + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.radio'); + $I->seeNodeChildren($label, array('input[type=radio]')); + } + + public function testCheckBoxControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::checkBoxControlGroup( + 'checkbox', + false, + array( + 'label' => 'Label text', + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.checkbox'); + $I->seeNodeChildren($label, array('input[type=checkbox]')); + } + + public function testDropDownListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::dropDownListControlGroup( + 'dropdown', + '', + array('1', '2', '3', '4', '5') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('select')); + } + + public function testListBoxControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::listBoxControlGroup( + 'listbox', + '', + array('1', '2', '3', '4', '5') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('select')); + } + + public function testRadioButtonListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::radioButtonListControlGroup( + 'radioList', + '1', + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('label.radio', 'label.radio', 'label.radio')); + } + + public function testInlineRadioButtonListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::inlineRadioButtonListControlGroup( + 'radioList', + '1', + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('label.radio.inline', 'label.radio.inline', 'label.radio.inline')); + } + + public function testCheckBoxListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::checkBoxListControlGroup( + 'checkboxList', + array('0', '2'), + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('label.checkbox', 'label.checkbox', 'label.checkbox')); + } + + public function testInlineCheckBoxListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::inlineCheckBoxListControlGroup( + 'checkboxList', + array('0', '2'), + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren( + $controls, + array('label.checkbox.inline', 'label.checkbox.inline', 'label.checkbox.inline') + ); + } + + public function testUneditableFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::uneditableFieldControlGroup('Uneditable text'); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('span.uneditable-input')); + } + + public function testSearchQueryControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::searchQueryControlGroup('Search query'); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input[type=text].search-query')); + } + + public function testControlGroup() + { + $I = $this->codeGuy; + + $html = TbHtml::controlGroup( + TbHtml::INPUT_TYPE_TEXT, + 'text', + '', + array( + 'color' => TbHtml::INPUT_COLOR_SUCCESS, + 'groupOptions' => array('class' => 'group'), + 'label' => 'Label text', + 'labelOptions' => array('class' => 'label'), + 'help' => 'Help text', + 'helpOptions' => array('class' => 'help'), + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeCssClass($group, 'success group'); + $I->seeNodeChildren($group, array('label.control-label', 'div.controls')); + $label = $group->filter('label.control-label'); + $I->seeNodeCssClass($label, 'label'); + $I->seeNodeAttribute($label, 'for', 'text'); + $I->seeNodeText($label, 'Label text'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input', 'span')); + $input = $controls->filter('input[type=text]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'text', + 'name' => 'text', + 'value' => '', + ) + ); + $help = $controls->filter('span.help-inline'); + $I->seeNodeCssClass($help, 'help'); + $I->seeNodeText($help, 'Help text'); + + $html = TbHtml::controlGroup( + TbHtml::INPUT_TYPE_RADIOBUTTON, + 'radio', + true, + array( + 'label' => 'Label text', + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeChildren($group, array('div.controls')); + $controls = $group->filter('div.controls'); + $label = $controls->filter('label.radio'); + $I->seeNodePattern($label, '/> Label text$/'); + $radio = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $radio, + array( + 'checked' => 'checked', + 'id' => 'radio', + 'name' => 'radio', + 'value' => '1', + ) + ); + } + + public function testCustomControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::customControlGroup( + '
', + 'custom', + array( + 'label' => false, + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('div.widget')); + } + + public function testActiveTextField() + { + $I = $this->codeGuy; + + $html = TbHtml::activeTextField( + new Dummy, + 'text', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=text]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_text', + 'name' => 'Dummy[text]', + 'value' => 'text', + ) + ); + + $html = TbHtml::activeTextField( + new Dummy, + 'text', + array( + 'prepend' => 'Prepend text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-prepend'); + $I->seeNodeChildren($div, array('span.add-on', 'input')); + $span = $div->filter('span.add-on'); + $I->seeNodeText($span, 'Prepend text'); + + $html = TbHtml::activeTextField( + new Dummy, + 'text', + array( + 'append' => 'Append text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-append'); + $I->seeNodeChildren($div, array('input', 'span')); + $span = $div->filter('span.add-on'); + $I->seeNodeText($span, 'Append text'); + + $html = TbHtml::activeTextField( + new Dummy, + 'text', + array( + 'prepend' => 'Prepend text', + 'append' => 'Append text', + ) + ); + $div = $I->createNode($html, 'div'); + $I->seeNodeCssClass($div, 'input-prepend input-append'); + $I->seeNodeChildren($div, array('span.add-on', 'input', 'span.add-on')); + } + + public function testActivePasswordField() + { + $I = $this->codeGuy; + $html = TbHtml::activePasswordField( + new Dummy, + 'password', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=password]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_password', + 'name' => 'Dummy[password]', + 'value' => 'secret', + ) + ); + } + + public function testActiveUrlField() + { + $I = $this->codeGuy; + $html = TbHtml::activeUrlField( + new Dummy, + 'url', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=url]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_url', + 'name' => 'Dummy[url]', + 'value' => 'http://www.getyiistrap.com', + ) + ); + } + + public function testActiveEmailField() + { + $I = $this->codeGuy; + $html = TbHtml::activeEmailField( + new Dummy, + 'email', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=email]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_email', + 'name' => 'Dummy[email]', + 'value' => 'christoffer.niska@gmail.com', + ) + ); + } + + public function testActiveNumberField() + { + $I = $this->codeGuy; + $html = TbHtml::activeNumberField( + new Dummy, + 'number', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=number]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_number', + 'name' => 'Dummy[number]', + 'value' => '42', + ) + ); + } + + public function testActiveRangeField() + { + $I = $this->codeGuy; + $html = TbHtml::activeRangeField( + new Dummy, + 'range', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=range]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_range', + 'name' => 'Dummy[range]', + 'value' => '3.33', + ) + ); + } + + public function testActiveDateField() + { + $I = $this->codeGuy; + $html = TbHtml::activeDateField( + new Dummy, + 'date', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=date]'); + $I->seeNodeAttributes( + $input, + array( + 'class' => 'input', + 'id' => 'Dummy_date', + 'name' => 'Dummy[date]', + 'value' => '2013-08-28', + ) + ); + } + + public function testActiveTextArea() + { + $I = $this->codeGuy; + $html = TbHtml::activeTextArea( + new Dummy, + 'textarea', + array( + 'class' => 'textarea', + ) + ); + $textarea = $I->createNode($html, 'textarea'); + $I->seeNodeAttributes( + $textarea, + array( + 'class' => 'textarea', + 'id' => 'Dummy_textarea', + 'name' => 'Dummy[textarea]', + ) + ); + $I->seeNodeText($textarea, 'Textarea text'); + } + + public function testActiveRadioButton() + { + $I = $this->codeGuy; + $html = TbHtml::activeRadioButton( + new Dummy, + 'radio', + array( + 'class' => 'input', + 'label' => 'Label text', + ) + ); + $body = $I->createNode($html, 'body'); + $hidden = $body->filter('input[type=hidden]'); + $I->seeNodeAttributes( + $hidden, + array( + 'id' => 'ytDummy_radio', + 'name' => 'Dummy[radio]', + 'value' => '0', + ) + ); + $label = $body->filter('label'); + $I->seeNodeCssClass($label, 'radio'); + $radio = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $radio, + array( + 'class' => 'input', + 'checked' => 'checked', + 'id' => 'Dummy_radio', + 'name' => 'Dummy[radio]', + 'value' => '1', + ) + ); + $I->seeNodePattern($label, '/> Label text$/'); + } + + public function testActiveCheckBox() + { + $I = $this->codeGuy; + $html = TbHtml::activeCheckBox( + new Dummy, + 'checkbox', + array( + 'class' => 'input', + 'label' => 'Label text', + ) + ); + $body = $I->createNode($html, 'body'); + $hidden = $body->filter('input[type=hidden]'); + $I->seeNodeAttributes( + $hidden, + array( + 'id' => 'ytDummy_checkbox', + 'name' => 'Dummy[checkbox]', + 'value' => '0', + ) + ); + $label = $body->filter('label'); + $I->seeNodeCssClass($label, 'checkbox'); + $checkbox = $label->filter('input[type=checkbox]'); + $I->seeNodeAttributes( + $checkbox, + array( + 'class' => 'input', + 'id' => 'Dummy_checkbox', + 'name' => 'Dummy[checkbox]', + 'value' => '1', + ) + ); + $I->seeNodePattern($label, '/> Label text$/'); + } + + public function testActiveDropDownList() + { + $I = $this->codeGuy; + $html = TbHtml::activeDropDownList( + new Dummy, + 'dropdown', + array('1', '2', '3', '4', '5'), + array( + 'class' => 'list', + 'empty' => 'Empty text', + 'size' => TbHtml::INPUT_SIZE_LARGE, + 'textAlign' => TbHtml::TEXT_ALIGN_CENTER, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeCssClass($select, 'input-large text-center list'); + $I->dontSeeNodeAttribute($select, 'size'); + } + + public function testActiveListBox() + { + $I = $this->codeGuy; + + $html = TbHtml::activeListBox( + new Dummy, + 'listbox', + array('1', '2', '3', '4', '5'), + array( + 'class' => 'list', + 'empty' => 'Empty text', + 'size' => TbHtml::INPUT_SIZE_LARGE, + 'textAlign' => TbHtml::TEXT_ALIGN_CENTER, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeCssClass($select, 'input-large text-center list'); + $I->seeNodeAttributes( + $select, + array( + 'name' => 'Dummy[listbox]', + 'id' => 'Dummy_listbox', + 'size' => 4, + ) + ); + + $html = TbHtml::activeListBox( + new Dummy, + 'listbox', + array('1', '2', '3', '4', '5'), + array( + 'multiple' => true, + ) + ); + $select = $I->createNode($html, 'select'); + $I->seeNodeAttribute($select, 'name', 'Dummy[listbox][]'); + } + + public function testActiveRadioButtonList() + { + // todo: ensure that this test is actually correct. + $I = $this->codeGuy; + $html = TbHtml::activeRadioButtonList( + new Dummy, + 'radioList', + array('Option 1', 'Option 2', 'Option 3') + ); + $body = $I->createNode($html); + $I->seeNodeChildren( + $body, + array('input[type=hidden]', 'label.radio', 'label.radio', 'label.radio') + ); + $label = $body->filter('label')->first(); + $I->seeNodePattern($label, '/> Option 1$/'); + $input = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'Dummy_radioList_0', + 'name' => 'Dummy[radioList]', + 'value' => '0', + ) + ); + } + + public function testActiveInlineRadioButtonList() + { + $I = $this->codeGuy; + $html = TbHtml::activeInlineRadioButtonList( + new Dummy, + 'radioList', + array('Option 1', 'Option 2', 'Option 3') + ); + $container = $I->createNode($html); + $I->seeNodeChildren($container, array('label.radio.inline', 'label.radio.inline', 'label.radio.inline')); + } + + public function testActiveCheckBoxList() + { + // todo: ensure that this test is actually correct. + $I = $this->codeGuy; + $html = TbHtml::activeCheckBoxList( + new Dummy, + 'checkboxList', + array('Option 1', 'Option 2', 'Option 3') + ); + $container = $I->createNode($html); + $I->seeNodeChildren( + $container, + array('input[type=hidden]', 'label.checkbox', 'label.checkbox', 'label.checkbox') + ); + $label = $container->filter('label')->first(); + $I->seeNodePattern($label, '/> Option 1$/'); + $input = $label->filter('input[type=checkbox]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'Dummy_checkboxList_0', + 'name' => 'Dummy[checkboxList][]', + 'value' => '0', + ) + ); + } + + public function testActiveInlineCheckBoxList() + { + $I = $this->codeGuy; + $html = TbHtml::activeInlineCheckBoxList( + new Dummy, + 'checkboxList', + array('Option 1', 'Option 2', 'Option 3') + ); + $container = $I->createNode($html); + $I->seeNodeChildren( + $container, + array('label.checkbox.inline', 'label.checkbox.inline', 'label.checkbox.inline') + ); + } + + public function testActiveUneditableField() + { + $I = $this->codeGuy; + $html = TbHtml::activeUneditableField( + new Dummy, + 'uneditable', + array( + 'class' => 'span' + ) + ); + $span = $I->createNode($html, 'span.uneditable-input'); + $I->seeNodeCssClass($span, 'span'); + $I->seeNodeText($span, 'Uneditable text'); + } + + public function testActiveSearchQueryField() + { + $I = $this->codeGuy; + $model = new Dummy; + $html = TbHtml::activeSearchQueryField( + $model, + 'search', + array( + 'class' => 'input' + ) + ); + $input = $I->createNode($html, 'input[type=text].search-query'); + $I->seeNodeCssClass($input, 'input'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'Dummy_search', + 'name' => 'Dummy[search]', + 'value' => 'Search query', + ) + ); + } + + public function testActiveTextFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeTextFieldControlGroup(new Dummy, 'text'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=text]')); + } + + public function testActivePasswordFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activePasswordFieldControlGroup(new Dummy, 'password'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=password]')); + } + + public function testActiveUrlFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeUrlFieldControlGroup(new Dummy, 'url'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=url]')); + } + + public function testActiveEmailFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeEmailFieldControlGroup(new Dummy, 'email'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=email]')); + } + + public function testActiveNumberFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeNumberFieldControlGroup(new Dummy, 'number'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=number]')); + } + + public function testActiveRangeFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeRangeFieldControlGroup(new Dummy, 'range'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=range]')); + } + + public function testActiveDateFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeDateFieldControlGroup(new Dummy, 'date'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=date]')); + } + + public function testActiveFileFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeFileFieldControlGroup(new Dummy, 'file'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('input[type=file]')); + } + + public function testActiveTextAreaControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeTextAreaControlGroup(new Dummy, 'textarea'); + $group = $I->createNode($html, 'div.control-group'); + $label = $group->filter('label.control-label'); + $I->seeNodeChildren($label, array('textarea')); + } + + public function testActiveRadioButtonControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeRadioButtonControlGroup(new Dummy, 'radio'); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeChildren($group, array('input[type=hidden]', 'label.radio')); + $label = $group->filter('label.radio'); + $I->seeNodeChildren($label, array('input[type=radio]')); + } + + public function testActiveCheckBoxControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeCheckBoxControlGroup(new Dummy, 'checkbox'); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeChildren($group, array('input[type=hidden]', 'label.checkbox')); + $label = $group->filter('label.checkbox'); + $I->seeNodeChildren($label, array('input[type=checkbox]')); + } + + public function testActiveDropDownListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeDropDownListControlGroup( + new Dummy, + 'dropdown', + array('1', '2', '3', '4', '5') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('select')); + } + + public function testActiveListBoxControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeListBoxControlGroup( + new Dummy, + 'listbox', + array('1', '2', '3', '4', '5') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('select')); + } + + public function testActiveRadioButtonListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeRadioButtonListControlGroup( + new Dummy, + 'radioList', + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input[type=hidden]', 'label.radio', 'label.radio', 'label.radio')); + } + + public function testActiveInlineRadioButtonListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeInlineRadioButtonListControlGroup( + new Dummy, + 'radioList', + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren( + $controls, + array('input[type=hidden]', 'label.radio.inline', 'label.radio.inline', 'label.radio.inline') + ); + } + + public function testActiveCheckBoxListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeCheckBoxListControlGroup( + new Dummy, + 'checkboxList', + array('0', '2'), + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren( + $controls, + array('input[type=hidden]', 'label.checkbox', 'label.checkbox', 'label.checkbox') + ); + } + + public function testActiveInlineCheckBoxListControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeInlineCheckBoxListControlGroup( + new Dummy, + 'checkboxList', + array('0', '2'), + array('Option 1', 'Option 2', 'Option 3') + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren( + $controls, + array('input[type=hidden]', 'label.checkbox.inline', 'label.checkbox.inline', 'label.checkbox.inline') + ); + } + + public function testActiveUneditableFieldControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeUneditableFieldControlGroup(new Dummy, 'uneditable'); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('span.uneditable-input')); + } + + public function testActiveSearchQueryControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::activeSearchQueryControlGroup(new Dummy, 'search'); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input[type=text].search-query')); + } + + public function testActiveControlGroup() + { + $I = $this->codeGuy; + + $html = TbHtml::activeControlGroup( + TbHtml::INPUT_TYPE_TEXT, + new Dummy, + 'text', + array( + 'color' => TbHtml::INPUT_COLOR_ERROR, + 'groupOptions' => array('class' => 'group'), + 'labelOptions' => array('class' => 'label'), + 'help' => 'Help text', + 'helpOptions' => array('class' => 'help'), + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeCssClass($group, 'error group'); + $I->seeNodeChildren($group, array('label.control-label', 'div.controls')); + $label = $group->filter('label.control-label'); + $I->seeNodeCssClass($label, 'label'); + $I->seeNodeAttribute($label, 'for', 'Dummy_text'); + $I->seeNodeText($label, 'Text'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input', 'span')); + $input = $controls->filter('input[type=text]'); + $I->seeNodeAttributes( + $input, + array( + 'id' => 'Dummy_text', + 'name' => 'Dummy[text]', + 'value' => 'text', + ) + ); + $help = $controls->filter('span.help-inline'); + $I->seeNodeCssClass($help, 'help'); + $I->seeNodeText($help, 'Help text'); + + $html = TbHtml::activeControlGroup( + TbHtml::INPUT_TYPE_RADIOBUTTON, + new Dummy, + 'radio', + array( + 'labelOptions' => array('class' => 'label'), + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $I->seeNodeChildren($group, array('div.controls')); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('input[type=hidden]', 'label.radio')); + $hidden = $controls->filter('input[type=hidden]'); + $I->seeNodeAttributes( + $hidden, + array( + 'id' => 'ytDummy_radio', + 'name' => 'Dummy[radio]', + 'value' => '0', + ) + ); + $label = $controls->filter('label.radio'); + $I->seeNodePattern($label, '/> Radio$/'); + $radio = $label->filter('input[type=radio]'); + $I->seeNodeAttributes( + $radio, + array( + 'checked' => 'checked', + 'id' => 'Dummy_radio', + 'name' => 'Dummy[radio]', + 'value' => '1', + ) + ); + } + + public function testActiveCustomControlGroup() + { + $I = $this->codeGuy; + $html = TbHtml::customActiveControlGroup( + '
', + new Dummy, + 'text', + array( + 'label' => false, + ) + ); + $group = $I->createNode($html, 'div.control-group'); + $controls = $group->filter('div.controls'); + $I->seeNodeChildren($controls, array('div.widget')); + } + + public function testErrorSummary() + { + $I = $this->codeGuy; + $model = new Dummy; + $model->addError('text', 'Error text'); + $html = TbHtml::errorSummary( + $model, + 'Header text', + 'Footer text', + array( + 'class' => 'summary' + ) + ); + $div = $I->createNode($html, 'div.alert'); + $I->seeNodeCssClass($div, 'alert-block alert-error summary'); + $I->seeNodePattern($div, '/^Header text/'); + $I->seeNodePattern($div, '/Footer text$/'); + $li = $div->filter('ul > li')->first(); + $I->seeNodeText($li, 'Error text'); + } + + public function testError() + { + $I = $this->codeGuy; + $model = new Dummy; + $model->addError('text', 'Error text'); + $html = TbHtml::error( + $model, + 'text', + array( + 'class' => 'error', + ) + ); + $span = $I->createNode($html, 'span.help-inline'); + $I->seeNodeCssClass($span, 'error'); + $I->seeNodeText($span, 'Error text'); + } + + public function testControls() + { + $I = $this->codeGuy; + $html = TbHtml::controls( + '
', + array( + 'before' => 'Before text', + 'after' => 'After text', + ) + ); + $controls = $I->createNode($html, 'div.controls'); + $I->seeNodeChildren($controls, array('div.control', 'div.control')); + $I->seeNodePattern($controls, '/^Before textseeNodePattern($controls, '/>After text$/'); + } + + public function testControlsRow() + { + $I = $this->codeGuy; + $html = TbHtml::controlsRow( + array( + '
', + '
', + ) + ); + $controls = $I->createNode($html, 'div.controls'); + $I->seeNodeCssClass($controls, 'controls-row'); + $I->seeNodeChildren($controls, array('div.control', 'div.control')); + } + + public function testFormActions() + { + $I = $this->codeGuy; + + $html = TbHtml::formActions('
'); + $this->assertEquals( + '
', + $html + ); + $actions = $I->createNode($html, 'div.form-actions'); + $I->seeNodeChildren($actions, array('div.action', 'div.action')); + + $html = TbHtml::formActions( + array( + '
', + '
', + ) + ); + $actions = $I->createNode($html, 'div.form-actions'); + $I->seeNodeChildren($actions, array('div.action', 'div.action')); + } + + public function testSearchForm() + { + $I = $this->codeGuy; + $html = TbHtml::searchForm( + '#', + 'post', + array( + 'class' => 'form', + ) + ); + $form = $I->createNode($html, 'form.form-search'); + $I->seeNodeCssClass($form, 'form'); + $I->seeNodeAttributes( + $form, + array( + 'action' => '#', + 'method' => 'post' + ) + ); + $input = $form->filter('input[type=text]'); + $I->seeNodeCssClass($input, 'search-query'); + } + + public function testLink() + { + $I = $this->codeGuy; + $html = TbHtml::link( + 'Link', + '#', + array( + 'class' => 'link' + ) + ); + $a = $I->createNode($html, 'a.link'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Link'); + } + + public function testButton() + { + $I = $this->codeGuy; + $html = TbHtml::button( + 'Button', + array( + 'class' => 'button', + 'name' => 'button', + 'color' => TbHtml::BUTTON_COLOR_PRIMARY, + 'size' => TbHtml::BUTTON_SIZE_LARGE, + 'block' => true, + 'disabled' => true, + 'loading' => 'Loading text', + 'toggle' => true, + 'icon' => TbHtml::ICON_CHECK + ) + ); + $button = $I->createNode($html, 'button[type=button].btn'); + $I->seeNodeCssClass($button, 'btn-primary btn-large btn-block disabled button'); + $I->seeNodeAttributes( + $button, + array( + 'name' => 'button', + 'data-loading-text' => 'Loading text', + 'data-toggle' => 'button', + 'disabled' => 'disabled', + ) + ); + $I->seeNodeChildren($button, array('i.icon-check')); + $I->seeNodePattern($button, '/> Button$/'); + } + + public function testHtmlButton() + { + $I = $this->codeGuy; + $html = TbHtml::htmlButton( + 'Button', + array( + 'class' => 'button', + 'name' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=button].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttribute($button, 'name', 'button'); + $I->seeNodeText($button, 'Button'); + } + + public function testSubmitButton() + { + $I = $this->codeGuy; + $html = TbHtml::submitButton( + 'Submit', + array( + 'class' => 'button', + 'name' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=submit].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttribute($button, 'name', 'button'); + $I->seeNodeText($button, 'Submit'); + } + + public function testResetButton() + { + $I = $this->codeGuy; + $html = TbHtml::resetButton( + 'Reset', + array( + 'class' => 'button', + 'name' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=reset].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttribute($button, 'name', 'button'); + $I->seeNodeText($button, 'Reset'); + } + + public function testImageButton() + { + $I = $this->codeGuy; + $html = TbHtml::imageButton( + 'image.png', + array( + 'class' => 'button', + 'name' => 'button', + ) + ); + $button = $I->createNode($html, 'input[type=image].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttributes( + $button, + array( + 'name' => 'button', + 'src' => 'image.png', + ) + ); + } + + public function testLinkButton() + { + $I = $this->codeGuy; + $html = TbHtml::linkButton( + 'Link', + array( + 'class' => 'button', + ) + ); + $a = $I->createNode($html, 'a.btn'); + $I->seeNodeCssClass($a, 'button'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Link'); + } + + public function testAjaxLink() + { + $I = $this->codeGuy; + $html = TbHtml::ajaxLink( + 'Link', + '#', + array(), // todo: figure out a way to test the ajax options as well. + array( + 'id' => 'button', + 'class' => 'button', + ) + ); + $a = $I->createNode($html, 'a'); + $I->seeNodeCssClass($a, 'button'); + $I->seeNodeAttributes( + $a, + array( + 'id' => 'button', + 'href' => '#', + ) + ); + $I->seeNodeText($a, 'Link'); + } + + public function testAjaxButton() + { + $I = $this->codeGuy; + $html = TbHtml::ajaxButton( + 'Button', + '#', + array(), + array( + 'id' => 'button', + 'class' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=button].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttribute($button, 'id', 'button'); + $I->seeNodeText($button, 'Button'); + } + + public function testAjaxSubmitButton() + { + $I = $this->codeGuy; + $html = TbHtml::ajaxSubmitButton( + 'Submit', + '#', + array(), + array( + 'class' => 'button', + 'id' => 'button', + 'name' => 'button' + ) + ); + $button = $I->createNode($html, 'button[type=submit].btn'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttributes( + $button, + array( + 'id' => 'button', + 'name' => 'button' + ) + ); + $I->seeNodeText($button, 'Submit'); + } + + public function testImageRounded() + { + $I = $this->codeGuy; + $html = TbHtml::imageRounded( + 'image.png', + 'Alternative text', + array( + 'class' => 'image', + ) + ); + $img = $I->createNode($html, 'img.img-rounded'); + $I->seeNodeCssClass($img, 'image'); + $I->seeNodeAttributes( + $img, + array( + 'src' => 'image.png', + 'alt' => 'Alternative text', + ) + ); + } + + public function testImageCircle() + { + $I = $this->codeGuy; + $html = TbHtml::imageCircle( + 'image.png', + 'Alternative text', + array( + 'class' => 'image', + ) + ); + $img = $I->createNode($html, 'img.img-circle'); + $I->seeNodeCssClass($img, 'image'); + $I->seeNodeAttributes( + $img, + array( + 'src' => 'image.png', + 'alt' => 'Alternative text', + ) + ); + } + + public function testImagePolaroid() + { + $I = $this->codeGuy; + $html = TbHtml::imagePolaroid( + 'image.png', + 'Alternative text', + array( + 'class' => 'image', + ) + ); + $img = $I->createNode($html, 'img.img-polaroid'); + $I->seeNodeCssClass($img, 'image'); + $I->seeNodeAttributes( + $img, + array( + 'src' => 'image.png', + 'alt' => 'Alternative text', + ) + ); + } + + public function testIcon() + { + $I = $this->codeGuy; + + $html = TbHtml::icon( + TbHtml::ICON_CHECK, + array( + 'class' => 'icon', + ) + ); + $i = $I->createNode($html, 'i.icon-check'); + $I->seeNodeEmpty($i); + + $html = TbHtml::icon( + TbHtml::ICON_REMOVE, + array( + 'color' => TbHtml::ICON_COLOR_WHITE, + ) + ); + $i = $I->createNode($html, 'i.icon-remove'); + $I->seeNodeCssClass($i, 'icon-white'); + $I->seeNodeEmpty($i); + + $html = TbHtml::icon('pencil white'); + $i = $I->createNode($html, 'i.icon-pencil'); + $I->seeNodeCssClass($i, 'icon-white'); + $I->seeNodeEmpty($i); + + $html = TbHtml::icon(array()); + $this->assertEquals('', $html); + } + + public function testDropdownToggleLink() + { + $I = $this->codeGuy; + $html = TbHtml::dropdownToggleLink( + 'Link', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.btn.dropdown-toggle'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'data-toggle' => 'dropdown', + ) + ); + $I->seeNodePattern($a, '/^Link seeNodeChildren($a, array('b.caret')); + } + + public function testDropdownToggleButton() + { + $I = $this->codeGuy; + $html = TbHtml::dropdownToggleButton( + 'Button', + array( + 'class' => 'button', + 'name' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=button].btn.dropdown-toggle'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttributes( + $button, + array( + 'name' => 'button', + 'data-toggle' => 'dropdown', + ) + ); + $I->seeNodePattern($button, '/^Button seeNodeChildren($button, array('b.caret')); + } + + public function testDropdownToggleMenuLink() + { + $I = $this->codeGuy; + $html = TbHtml::dropdownToggleMenuLink( + 'Link', + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.dropdown-toggle'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'data-toggle' => 'dropdown', + ) + ); + $I->seeNodePattern($a, '/^Link seeNodeChildren($a, array('b.caret')); + } + + public function testButtonGroup() + { + $I = $this->codeGuy; + + $buttons = array( + array('label' => 'Left'), + array( + 'label' => 'Middle', + 'items' => array( + array('label' => 'Action', 'url' => '#'), + ), + 'htmlOptions' => array('color' => TbHtml::BUTTON_COLOR_INVERSE), + ), + array('label' => 'Right', 'visible' => false), + ); + + $html = TbHtml::buttonGroup( + $buttons, + array( + 'class' => 'div', + 'color' => TbHtml::BUTTON_COLOR_PRIMARY, + 'toggle' => TbHtml::BUTTON_TOGGLE_CHECKBOX, + ) + ); + $group = $I->createNode($html, 'div.btn-group'); + $I->seeNodeCssClass($group, 'div'); + $I->seeNodeAttribute($group, 'data-toggle', 'buttons-checkbox'); + $I->seeNodeNumChildren($group, 2); + foreach ($group->children() as $i => $btnElement) { + $btn = $I->createNode($btnElement); + if ($i === 1) { + $I->seeNodeChildren($btn, array('a.dropdown-toggle', 'ul.dropdown-menu')); + $a = $btn->filter('a.dropdown-toggle'); + $I->seeNodeCssClass($a, 'btn-inverse'); + $I->seeNodeText($a, 'Middle'); + } else { + $I->seeNodeCssClass($btn, 'btn'); + $I->seeNodeAttribute($btn, 'href', '#'); + $I->seeNodeCssClass($btn, 'btn-primary'); + $I->seeNodeText($btn, $buttons[$i]['label']); + } + } + + $html = TbHtml::buttonGroup(array()); + $this->assertEquals('', $html); + } + + public function testVerticalButtonGroup() + { + $I = $this->codeGuy; + $html = TbHtml::verticalButtonGroup( + array( + array('icon' => TbHtml::ICON_ALIGN_LEFT), + array('icon' => TbHtml::ICON_ALIGN_CENTER), + array('icon' => TbHtml::ICON_ALIGN_RIGHT), + array('icon' => TbHtml::ICON_ALIGN_JUSTIFY), + ) + ); + $group = $I->createNode($html, 'div.btn-group'); + $I->seeNodeCssClass($group, 'btn-group-vertical'); + } + + public function testButtonToolbar() + { + $I = $this->codeGuy; + + $groups = array( + array( + 'items' => array( + array('label' => '1', 'color' => TbHtml::BUTTON_COLOR_DANGER), + array('label' => '2'), + array('label' => '3'), + array('label' => '4'), + ), + 'htmlOptions' => array( + 'color' => TbHtml::BUTTON_COLOR_INVERSE, + ), + ), + array( + 'items' => array( + array('label' => '5'), + array('label' => '6'), + array('label' => '7'), + ) + ), + array( + 'visible' => false, + 'items' => array( + array('label' => '8'), + ) + ), + array( + 'items' => array() + ), + ); + + $html = TbHtml::buttonToolbar( + $groups, + array( + 'class' => 'div', + 'color' => TbHtml::BUTTON_COLOR_PRIMARY, + ) + ); + $toolbar = $I->createNode($html, 'div.btn-toolbar'); + $I->seeNodeCssClass($toolbar, 'div'); + foreach ($toolbar->children() as $i => $groupElement) { + $group = $I->createNode($groupElement); + $I->seeNodeCssClass($group, 'btn-group'); + foreach ($group->children() as $j => $btnElement) { + $btn = $I->createNode($btnElement); + $I->seeNodeCssClass($btn, 'btn'); + if ($i === 0) { + $I->seeNodeCssClass($btn, $j === 0 ? 'btn-danger' : 'btn-inverse'); + } else { + $I->seeNodeCssClass($btn, 'btn-primary'); + } + $I->seeNodeText($btn, $groups[$i]['items'][$j]['label']); + } + } + + $html = TbHtml::buttonToolbar(array()); + $this->assertEquals('', $html); + } + + public function testButtonDropdown() + { + $I = $this->codeGuy; + + $items = array( + array( + 'label' => 'Action', + 'url' => '#', + 'class' => 'item', + 'linkOptions' => array('class' => 'link'), + ), + array('label' => 'Another action', 'url' => '#'), + array('label' => 'Something else here', 'url' => '#'), + TbHtml::menuDivider(), + array('label' => 'Separate link', 'url' => '#'), + ); + + $html = TbHtml::buttonDropdown( + 'Action', + $items, + array( + 'class' => 'link', + 'dropup' => true, + 'groupOptions' => array('class' => 'group'), + 'menuOptions' => array('class' => 'menu'), + ) + ); + $group = $I->createNode($html, 'div.btn-group'); + $I->seeNodeCssClass($group, 'dropup group'); + $I->seeNodeChildren($group, array('a.dropdown-toggle', 'ul.dropdown-menu')); + $a = $group->filter('a.dropdown-toggle'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'data-toggle' => 'dropdown', + 'href' => '#', + ) + ); + $I->seeNodePattern($a, '/Action filter('b.caret'); + $I->seeNodeEmpty($b); + $ul = $group->filter('ul.dropdown-menu'); + foreach ($ul->children() as $i => $liElement) { + $li = $I->createNode($liElement); + if ($i === 3) { + $I->seeNodeCssClass($li, 'divider'); + } else { + $a = $li->filter('a'); + if ($i === 0) { + $I->seeNodeCssClass($li, 'item'); + $I->seeNodeCssClass($a, 'link'); + } + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'tabindex' => '-1', + ) + ); + $I->seeNodeText($a, $items[$i]['label']); + } + } + } + + public function testSplitButtonDropdown() + { + $I = $this->codeGuy; + + $items = array( + array('label' => 'Action', 'url' => '#'), + array('label' => 'Another action', 'url' => '#'), + array('label' => 'Something else here', 'url' => '#'), + TbHtml::menuDivider(), + array('label' => 'Separate link', 'url' => '#'), + ); + + $html = TbHtml::splitButtonDropdown('Action', $items); + $group = $I->createNode($html, 'div.btn-group'); + $I->seeNodeChildren($group, array('a.btn', 'button.dropdown-toggle', 'ul.dropdown-menu')); + CHtml::$count = 0; + } + + public function testTabs() + { + $I = $this->codeGuy; + $html = TbHtml::tabs( + array( + array('label' => 'Link', 'url' => '#'), + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-tabs'); + } + + public function testStackedTabs() + { + $I = $this->codeGuy; + $html = TbHtml::stackedTabs( + array( + array('label' => 'Link', 'url' => '#'), + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-tabs nav-stacked'); + } + + public function testPills() + { + $I = $this->codeGuy; + $html = TbHtml::pills( + array( + array('label' => 'Link', 'url' => '#'), + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-pills'); + } + + public function testStackedPills() + { + $I = $this->codeGuy; + + $html = TbHtml::stackedPills( + array( + array('label' => 'Link', 'url' => '#'), + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-pills nav-stacked'); + } + + public function testNavList() + { + $I = $this->codeGuy; + + $items = array( + array('label' => 'Header text'), + array('label' => 'Link', 'url' => '#'), + TbHtml::menuDivider(), + ); + + $html = TbHtml::navList( + $items, + array( + 'stacked' => true, + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-list'); + $I->dontSeeNodeCssClass($nav, 'nav-stacked'); + foreach ($nav->children() as $i => $liElement) { + $li = $I->createNode($liElement); + if ($i === 0) { + $I->seeNodeCssClass($li, 'nav-header'); + $I->seeNodeText($li, 'Header text'); + } else if ($i === 1) { + $a = $li->filter('a'); + $I->seeNodeText($a, $items[$i]['label']); + } else if ($i === 2) { + $I->seeNodeCssClass($li, 'divider'); + } + } + } + + public function testNav() + { + $I = $this->codeGuy; + $html = TbHtml::nav( + TbHtml::NAV_TYPE_NONE, + array( + array('label' => 'Link', 'url' => '#'), + ), + array( + 'stacked' => true, + ) + ); + $nav = $I->createNode($html, 'ul.nav'); + $I->seeNodeCssClass($nav, 'nav-stacked'); + } + + public function testMenu() + { + $I = $this->codeGuy; + + $items = array( + array('icon' => TbHtml::ICON_HOME, 'label' => 'Home', 'url' => '#'), + array('label' => 'Profile', 'url' => '#', 'htmlOptions' => array('disabled' => true)), + array('label' => 'Dropdown', 'active' => true, 'items' => array( + array('label' => 'Action', 'url' => '#'), + array('label' => 'Another action', 'url' => '#'), + array('label' => 'Dropdown', 'items' => array( + array('label' => 'Action', 'url' => '#'), + )), + TbHtml::menuDivider(), + array('label' => 'Separate link', 'url' => '#'), + )), + array('label' => 'Hidden', 'url' => '#', 'visible' => false), + ); + + $html = TbHtml::menu( + $items, + array( + 'class' => 'ul', + ) + ); + $nav = $I->createNode($html, 'ul'); + $I->seeNodeAttribute($nav, 'role', 'menu'); + $I->seeNodeNumChildren($nav, 3); + foreach ($nav->children() as $i => $liElement) { + $li = $I->createNode($liElement); + if ($i === 2) { + $I->seeNodeCssClass($li, 'dropdown active'); + $I->seeNodeChildren($li, array('a.dropdown-toggle', 'ul.dropdown-menu')); + $ul = $li->filter('ul.dropdown-menu'); + $I->seeNodeNumChildren($ul, 5); + foreach ($ul->children() as $j => $subLiElement) { + $subLi = $I->createNode($subLiElement); + if ($j === 2) { + $I->seeNodeCssClass($subLi, 'dropdown-submenu'); + $I->seeNodeChildren($subLi, array('a.dropdown-toggle', 'ul.dropdown-menu')); + $subUl = $subLi->filter('ul.dropdown-menu'); + $I->seeNodeNumChildren($subUl, 1); + } else { + if ($j === 3) { + $I->seeNodeCssClass($subLi, 'divider'); + } else { + $subA = $subLi->filter('a'); + $I->seeNodeText($subA, $items[$i]['items'][$j]['label']); + } + } + } + } else { + if ($i === 0) { + $I->seeNodeChildren($li, array('i.icon-home', 'a')); + } + if ($i === 2) { + $I->seeNodeCssClass($li, 'disabled'); + } + $a = $li->filter('a'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'tabindex' => '-1', + ) + ); + $I->seeNodeText($a, $items[$i]['label']); + } + } + + $html = TbHtml::menu(array()); + $this->assertEquals('', $html); + } + + public function testMenuLink() + { + $I = $this->codeGuy; + $html = TbHtml::menuLink( + 'Link', + '#', + array( + 'class' => 'item', + 'linkOptions' => array('class' => 'link'), + ) + ); + $li = $I->createNode($html, 'li'); + $I->seeNodeCssClass($li, 'item'); + $a = $li->filter('a'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Link'); + } + + public function testMenuHeader() + { + $I = $this->codeGuy; + $html = TbHtml::menuHeader( + 'Header text', + array( + 'class' => 'item', + ) + ); + $li = $I->createNode($html, 'li.nav-header'); + $I->seeNodeCssClass($li, 'item'); + $I->seeNodeText($li, 'Header text'); + } + + public function testMenuDivider() + { + $I = $this->codeGuy; + $html = TbHtml::menuDivider( + array( + 'class' => 'item', + ) + ); + $li = $I->createNode($html, 'li.divider'); + $I->seeNodeCssClass($li, 'item'); + $I->seeNodeEmpty($li); + } + + public function testTabbableTabs() + { + $I = $this->codeGuy; + $html = TbHtml::tabbableTabs( + array( + array('label' => 'Link', 'content' => 'Tab content'), + ) + ); + $tabbable = $I->createNode($html, 'div.tabbable'); + $ul = $tabbable->filter('ul.nav'); + $I->seeNodeCssClass($ul, 'nav-tabs'); + } + + public function testTabbablePills() + { + $I = $this->codeGuy; + $html = TbHtml::tabbablePills( + array( + array('label' => 'Link', 'content' => 'Tab content'), + ) + ); + $tabbable = $I->createNode($html, 'div.tabbable'); + $ul = $tabbable->filter('ul.nav'); + $I->seeNodeCssClass($ul, 'nav-pills'); + } + + public function testTabbable() + { + $I = $this->codeGuy; + + $tabs = array( + array('label' => 'Home', 'content' => 'Tab content', 'active' => true), + array('label' => 'Profile', 'content' => 'Tab content', 'id' => 'profile'), + array( + 'label' => 'Messages', + 'items' => array( + array('label' => '@fat', 'content' => 'Tab content'), + array('label' => '@mdo', 'content' => 'Tab content'), + ) + ), + ); + + $html = TbHtml::tabbable( + TbHtml::NAV_TYPE_NONE, + $tabs, + array( + 'class' => 'div', + ) + ); + $tabbable = $I->createNode($html, 'div.tabbable'); + $I->seeNodeCssClass($tabbable, 'div'); + $ul = $tabbable->filter('ul.nav'); + $I->seeNodeNumChildren($ul, 3); + foreach ($ul->children() as $i => $liElement) { + $li = $I->createNode($liElement); + if ($i === 0) { + $I->seeNodeCssClass($li, 'active'); + } + if ($i === 2) { + $I->seeNodeCssClass($li, 'dropdown'); + $a = $li->filter('a.dropdown-toggle'); + $I->seeNodeText($a, 'Messages'); + $subUl = $li->filter('ul.dropdown-menu'); + foreach ($subUl->children() as $j => $subLiElement) { + $subLi = $I->createNode($subLiElement); + $subA = $subLi->filter('a'); + $I->seeNodeAttributes( + $subA, + array( + 'data-toggle' => 'tab', + 'tabindex' => '-1', + 'href' => '#tab_' . ($i + $j + 1), + ) + ); + $I->seeNodeText($subA, $tabs[$i]['items'][$j]['label']); + } + } else { + $a = $li->filter('a'); + $I->seeNodeAttributes( + $a, + array( + 'data-toggle' => 'tab', + 'tabindex' => '-1', + 'href' => '#' . (isset($tabs[$i]['id']) ? $tabs[$i]['id'] : 'tab_' . ($i + 1)), + ) + ); + $I->seeNodeText($a, $tabs[$i]['label']); + } + } + $content = $tabbable->filter('div.tab-content'); + $I->seeNodeNumChildren($content, 4); + foreach ($content->children() as $i => $paneElement) { + $pane = $I->createNode($paneElement); + $I->seeNodeCssClass($pane, 'tab-pane fade'); + if ($i === 0) { + $I->seeNodeCssClass($pane, 'active in'); + } + if ($i > 1) { + $I->seeNodeText($pane, $tabs[2]['items'][$i - 2]['content']); + } else { + $I->seeNodeText($pane, $tabs[$i]['content']); + } + } + } + + public function testNavbar() + { + $I = $this->codeGuy; + + $html = TbHtml::navbar( + 'Navbar content', + array( + 'class' => 'nav', + 'innerOptions' => array('class' => 'inner'), + ) + ); + $navbar = $I->createNode($html, 'div.navbar'); + $I->seeNodeCssClass($navbar, 'nav'); + $inner = $navbar->filter('div.navbar-inner'); + $I->seeNodeText($inner, 'Navbar content'); + + $html = TbHtml::navbar( + '', + array( + 'display' => TbHtml::NAVBAR_DISPLAY_STATICTOP, + ) + ); + $navbar = $I->createNode($html, 'div.navbar'); + $I->seeNodeCssClass($navbar, 'navbar-static-top'); + + $html = TbHtml::navbar( + '', + array( + 'display' => TbHtml::NAVBAR_DISPLAY_FIXEDTOP, + ) + ); + $navbar = $I->createNode($html, 'div.navbar'); + $I->seeNodeCssClass($navbar, 'navbar-fixed-top'); + + $html = TbHtml::navbar( + '', + array( + 'display' => TbHtml::NAVBAR_DISPLAY_FIXEDBOTTOM, + ) + ); + $navbar = $I->createNode($html, 'div.navbar'); + $I->seeNodeCssClass($navbar, 'navbar-fixed-bottom'); + + $html = TbHtml::navbar( + '', + array( + 'color' => TbHtml::NAVBAR_COLOR_INVERSE, + ) + ); + $navbar = $I->createNode($html, 'div.navbar'); + $I->seeNodeCssClass($navbar, 'navbar-inverse'); + } + + public function testNavbarBrandLink() + { + $I = $this->codeGuy; + $html = TbHtml::navbarBrandLink( + 'Brand text', + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.brand'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Brand text'); + } + + public function testNavbarText() + { + $I = $this->codeGuy; + $html = TbHtml::navbarText( + 'Navbar text', + array( + 'class' => 'text', + ) + ); + $p = $I->createNode($html, 'p.navbar-text'); + $I->seeNodeCssClass($p, 'text'); + $I->seeNodeText($p, 'Navbar text'); + } + + public function testNavbarMenuDivider() + { + $I = $this->codeGuy; + $html = TbHtml::navbarMenuDivider( + array( + 'class' => 'item', + ) + ); + $li = $I->createNode($html, 'li.divider-vertical'); + $I->seeNodeCssClass($li, 'item'); + $I->seeNodeEmpty($li); + } + + public function testNavbarForm() + { + $I = $this->codeGuy; + $html = TbHtml::navbarForm('#'); + $I->createNode($html, 'form.navbar-form'); + } + + public function testNavbarSearchForm() + { + $I = $this->codeGuy; + $html = TbHtml::navbarSearchForm('#'); + $I->createNode($html, 'form.navbar-search'); + } + + public function testNavbarCollapseLink() + { + $I = $this->codeGuy; + $html = TbHtml::navbarCollapseLink( + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.btn.btn-navbar'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'data-toggle' => 'collapse', + 'data-target' => '#', + ) + ); + $I->seeNodeChildren($a, array('span.icon-bar', 'span.icon-bar', 'span.icon-bar')); + } + + public function testBreadcrumbs() + { + $I = $this->codeGuy; + + $links = array( + 'Home' => '#', + 'Library' => '#', + 'Data', + ); + + $html = TbHtml::breadcrumbs( + $links, + array( + 'class' => 'ul', + ) + ); + $ul = $I->createNode($html, 'ul.breadcrumb'); + $I->seeNodeCssClass($ul, 'ul'); + $I->seeNodeNumChildren($ul, 3); + foreach ($ul->children() as $i => $liElement) { + $li = $I->createNode($liElement); + switch ($i) { + case 0: + $a = $li->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Home'); + break; + case 1: + $a = $li->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Library'); + break; + case 2: + $I->seeNodeText($li, 'Data'); + break; + } + } + } + + public function testPagination() + { + $I = $this->codeGuy; + + $items = array( + array('label' => 'Prev', 'url' => '#', 'disabled' => true), + array( + 'label' => '1', + 'url' => '#', + 'active' => true, + 'htmlOptions' => array('class' => 'item'), + 'linkOptions' => array('class' => 'link'), + ), + array('label' => '2', 'url' => '#'), + array('label' => '3', 'url' => '#'), + array('label' => '4', 'url' => '#'), + array('label' => '5', 'url' => '#'), + array('label' => 'Next', 'url' => '#'), + ); + + $html = TbHtml::pagination( + $items, + array( + 'class' => 'div', + 'listOptions' => array('class' => 'list'), + ) + ); + $div = $I->createNode($html, 'div.pagination'); + $I->seeNodeCssClass($div, 'div'); + $ul = $div->filter('ul'); + $I->seeNodeCssClass($ul, 'list'); + $I->seeNodeNumChildren($ul, 7); + foreach ($ul->children() as $i => $liElement) { + $li = $I->createNode($liElement); + $a = $li->filter('a'); + if ($i === 0) { + $I->seeNodeCssClass($li, 'disabled'); + } + if ($i === 1) { + $I->seeNodeCssClass($li, 'item active'); + $I->seeNodeCssClass($a, 'link'); + } + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, $items[$i]['label']); + } + + $html = TbHtml::pagination( + $items, + array( + 'size' => TbHtml::PAGINATION_SIZE_LARGE, + ) + ); + $div = $I->createNode($html, 'div.pagination'); + $I->seeNodeCssClass($div, 'pagination-large'); + + $html = TbHtml::pagination( + $items, + array( + 'align' => TbHtml::PAGINATION_ALIGN_CENTER, + ) + ); + $div = $I->createNode($html, 'div.pagination'); + $I->seeNodeCssClass($div, 'pagination-centered'); + + $html = TbHtml::pagination(array()); + $this->assertEquals('', $html); + } + + public function testPaginationLink() + { + $I = $this->codeGuy; + $html = TbHtml::paginationLink( + 'Link', + '#', + array( + 'class' => 'item', + 'linkOptions' => array('class' => 'link'), + ) + ); + $li = $I->createNode($html, 'li'); + $I->seeNodeCssClass($li, 'item'); + $a = $li->filter('a'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + } + + public function testPager() + { + $I = $this->codeGuy; + + $items = array( + array( + 'label' => 'Prev', + 'url' => '#', + 'previous' => true, + 'htmlOptions' => array('disabled' => true), + ), + array('label' => 'Next', 'url' => '#', 'next' => true), + ); + + $html = TbHtml::pager( + $items, + array( + 'class' => 'list', + ) + ); + $ul = $I->createNode($html, 'ul.pager'); + $I->seeNodeCssClass($ul, 'list'); + $I->seeNodeNumChildren($ul, 2); + $prev = $ul->filter('li')->first(); + $I->seeNodeCssClass($prev, 'previous disabled'); + $a = $prev->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Prev'); + $next = $ul->filter('li')->last(); + $I->seeNodeCssClass($next, 'next'); + $a = $next->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Next'); + + $html = TbHtml::pager(array()); + $this->assertEquals('', $html); + } + + public function testPagerLink() + { + $I = $this->codeGuy; + + $html = TbHtml::pagerLink( + 'Link', + '#', + array( + 'class' => 'item', + 'linkOptions' => array('class' => 'link'), + 'disabled' => true, + ) + ); + $li = $I->createNode($html, 'li'); + $I->seeNodeCssClass($li, 'item disabled'); + $a = $li->filter('a'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Link'); + + $html = TbHtml::pagerLink( + 'Previous', + '#', + array( + 'previous' => true, + ) + ); + $li = $I->createNode($html, 'li.previous'); + $a = $li->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Previous'); + + $html = TbHtml::pagerLink( + 'Next', + '#', + array( + 'next' => true, + ) + ); + $li = $I->createNode($html, 'li.next'); + $a = $li->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Next'); + } + + public function testLabel() + { + $I = $this->codeGuy; + $html = TbHtml::labelTb( + 'Label text', + array( + 'color' => TbHtml::LABEL_COLOR_INFO, + 'class' => 'span', + ) + ); + $span = $I->createNode($html, 'span.label'); + $I->seeNodeCssClass($span, 'label-info span'); + $I->seeNodeText($span, 'Label text'); + } + + public function testBadge() + { + $I = $this->codeGuy; + $html = TbHtml::badge( + 'Badge text', + array( + 'color' => TbHtml::BADGE_COLOR_WARNING, + 'class' => 'span', + ) + ); + $span = $I->createNode($html, 'span.badge'); + $I->seeNodeCssClass($span, 'badge-warning span'); + $I->seeNodeText($span, 'Badge text'); + } + + public function testHeroUnit() + { + $I = $this->codeGuy; + $html = TbHtml::heroUnit( + 'Heading text', + 'Content text', + array( + 'class' => 'div', + 'headingOptions' => array('class' => 'heading'), + ) + ); + $hero = $I->createNode($html, 'div.hero-unit'); + $I->seeNodeCssClass($hero, 'div'); + $I->seeNodeText($hero, 'Content text'); + $h1 = $hero->filter('h1'); + $I->seeNodeCssClass($h1, 'heading'); + $I->seeNodeText($h1, 'Heading text'); + } + + public function testPageHeader() + { + $I = $this->codeGuy; + $html = TbHtml::pageHeader( + 'Heading text', + 'Subtext', + array( + 'class' => 'header', + 'headerOptions' => array('class' => 'heading'), + 'subtextOptions' => array('class' => 'subtext') + ) + ); + $header = $I->createNode($html, 'div.page-header'); + $I->seeNodeCssClass($header, 'header'); + $h1 = $header->filter('h1'); + $I->seeNodeCssClass($h1, 'heading'); + $I->seeNodeText($h1, 'Heading text'); + $small = $h1->filter('small'); + $I->seeNodeCssClass($small, 'subtext'); + $I->seeNodeText($small, 'Subtext'); + } + + public function testThumbnails() + { + $I = $this->codeGuy; + + $items = array( + array( + 'image' => 'image.png', + 'label' => 'Thumbnail label', + 'caption' => 'Caption text', + 'span' => 6, + 'imageOptions' => array('class' => 'image', 'alt' => 'Alternative text'), + 'captionOptions' => array('class' => 'div'), + 'labelOptions' => array('class' => 'heading'), + ), + array('image' => 'image.png', 'label' => 'Thumbnail label', 'caption' => 'Caption text'), + array('image' => 'image.png', 'label' => 'Thumbnail label', 'caption' => 'Caption text'), + ); + + $html = TbHtml::thumbnails( + $items, + array( + 'span' => 3, + 'class' => 'list', + ) + ); + $thumbnails = $I->createNode($html, 'ul.thumbnails'); + $I->seeNodeCssClass($thumbnails, 'list'); + $I->seeNodeNumChildren($thumbnails, 3); + $I->seeNodeChildren($thumbnails, array('li.span6', 'li.span3', 'li.span3')); + foreach ($thumbnails->children() as $i => $liElement) { + $li = $I->createNode($liElement); + $thumbnail = $li->filter('div.thumbnail'); + $I->seeNodeChildren($thumbnail, array('img', 'div.caption')); + $img = $thumbnail->filter('img'); + $I->seeNodeAttribute($img, 'src', 'image.png'); + $caption = $thumbnail->filter('div.caption'); + $h3 = $caption->filter('h3'); + $I->seeNodeText($caption, $items[$i]['caption']); + $I->seeNodeText($h3, $items[$i]['label']); + if ($i === 0) { + $I->seeNodeCssClass($img, 'image'); + $I->seeNodeAttribute($img, 'alt', 'Alternative text'); + $I->seeNodeCssClass($caption, 'div'); + $I->seeNodeCssClass($h3, 'heading'); + } + } + + $html = TbHtml::thumbnails(array()); + $this->assertEquals('', $html); + } + + public function testThumbnail() + { + $I = $this->codeGuy; + $html = TbHtml::thumbnail( + 'Thumbnail text', + array( + 'class' => 'div', + 'itemOptions' => array('class' => 'item'), + ) + ); + $li = $I->createNode($html, 'li'); + $I->seeNodeCssClass($li, 'item'); + $thumbnail = $li->filter('div.thumbnail'); + $I->seeNodeCssClass($thumbnail, 'div'); + $I->seeNodeText($thumbnail, 'Thumbnail text'); + } + + public function testThumbnailLink() + { + $I = $this->codeGuy; + $html = TbHtml::thumbnailLink( + 'Thumbnail text', + '#', + array( + 'class' => 'link', + 'itemOptions' => array('class' => 'item'), + ) + ); + $li = $I->createNode($html, 'li'); + $I->seeNodeCssClass($li, 'item'); + $thumbnail = $li->filter('a.thumbnail'); + $I->seeNodeCssClass($thumbnail, 'link'); + $I->seeNodeAttribute($thumbnail, 'href', '#'); + $I->seeNodeText($thumbnail, 'Thumbnail text'); + } + + public function testAlert() + { + $I = $this->codeGuy; + + $html = TbHtml::alert( + TbHtml::ALERT_COLOR_SUCCESS, + 'Alert message', + array( + 'class' => 'div', + 'closeText' => 'Close', + 'closeOptions' => array('class' => 'text'), + ) + ); + $alert = $I->createNode($html, 'div.alert'); + $I->seeNodeCssClass($alert, 'alert-success in fade div'); + $I->seeNodeText($alert, 'Alert message'); + $close = $alert->filter('a[type=button].close'); + $I->seeNodeCssClass($close, 'text'); + $I->seeNodeAttributes( + $close, + array( + 'href' => '#', + 'data-dismiss' => 'alert', + ) + ); + $I->seeNodeText($close, 'Close'); + + $html = TbHtml::alert( + TbHtml::ALERT_COLOR_INFO, + 'Alert message', + array( + 'closeText' => false, + 'in' => false, + 'fade' => false, + ) + ); + $alert = $I->createNode($html, 'div.alert'); + $I->seeNodeCssClass($alert, 'alert-info'); + $I->dontSeeNodeCssClass($alert, 'fade in'); + $I->dontSeeNodeChildren($alert, array('.close')); + $I->seeNodeText($alert, 'Alert message'); + } + + public function testBlockAlert() + { + $I = $this->codeGuy; + $html = TbHtml::blockAlert(TbHtml::ALERT_COLOR_WARNING, 'Alert message'); + $alert = $I->createNode($html, 'div.alert'); + $I->seeNodeCssClass($alert, 'alert-warning alert-block fade in'); + $I->seeNodeText($alert, 'Alert message'); + $I->seeNodeChildren($alert, array('div.alert > a[type=button].close')); + } + + public function testProgressBar() + { + $I = $this->codeGuy; + + $html = TbHtml::progressBar( + 60, + array( + 'class' => 'div', + 'color' => TbHtml::PROGRESS_COLOR_INFO, + 'content' => 'Bar text', + 'barOptions' => array('class' => 'div'), + ) + ); + $progress = $I->createNode($html, 'div.progress'); + $I->seeNodeCssClass($progress, 'progress-info div'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssClass($bar, 'div'); + $I->seeNodeCssStyle($bar, 'width: 60%'); + $I->seeNodeText($bar, 'Bar text'); + + $html = TbHtml::progressBar( + 35, + array( + 'barOptions' => array('color' => TbHtml::PROGRESS_COLOR_SUCCESS), + ) + ); + $progress = $I->createNode($html, 'div.progress'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssClass($bar, 'bar-success'); + $I->seeNodeCssStyle($bar, 'width: 35%'); + + $html = TbHtml::progressBar(-1); + $progress = $I->createNode($html, 'div.progress'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssStyle($bar, 'width: 0'); + + $html = TbHtml::progressBar(100.1); + $progress = $I->createNode($html, 'div.progress'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssStyle($bar, 'width: 100%'); + } + + public function testStripedProgressBar() + { + $I = $this->codeGuy; + $html = TbHtml::stripedProgressBar(20); + $progress = $I->createNode($html, 'div.progress'); + $I->seeNodeCssClass($progress, 'progress-striped'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssStyle($bar, 'width: 20%'); + } + + public function testAnimatedProgressBar() + { + $I = $this->codeGuy; + $html = TbHtml::animatedProgressBar(40); + $progress = $I->createNode($html, 'div.progress'); + $I->seeNodeCssClass($progress, 'progress-striped active'); + $bar = $progress->filter('div.bar'); + $I->seeNodeCssStyle($bar, 'width: 40%'); + } + + public function testStackedProgressBar() + { + $I = $this->codeGuy; + + $html = TbHtml::stackedProgressBar( + array( + array('color' => TbHtml::PROGRESS_COLOR_SUCCESS, 'width' => 35), + array('color' => TbHtml::PROGRESS_COLOR_WARNING, 'width' => 20), + array('color' => TbHtml::PROGRESS_COLOR_DANGER, 'width' => 10), + ) + ); + $progress = $I->createNode($html, 'div.progress'); + $I->seeNodeChildren($progress, array('div.bar-success', 'div.bar-warning', 'div.bar-danger')); + $success = $progress->filter('div.bar-success'); + $I->seeNodeCssClass($success, 'bar'); + $I->seeNodeCssStyle($success, 'width: 35%'); + $warning = $progress->filter('div.bar-warning'); + $I->seeNodeCssClass($warning, 'bar'); + $I->seeNodeCssStyle($warning, 'width: 20%'); + $danger = $progress->filter('div.bar-danger'); + $I->seeNodeCssClass($danger, 'bar'); + $I->seeNodeCssStyle($danger, 'width: 10%'); + + $html = TbHtml::stackedProgressBar( + array( + array('width' => 35), + array('width' => 20), + array('width' => 100), + ) + ); + $progress = $I->createNode($html, 'div.progress'); + $last = $progress->filter('div.bar')->last(); + $I->seeNodeCssStyle($last, 'width: 45%'); + + $html = TbHtml::stackedProgressBar( + array( + array('width' => 35), + array('width' => 20), + array('width' => 10, 'visible' => false), + ) + ); + $progress = $I->createNode($html, 'div.progress'); + $last = $progress->filter('div.bar')->last(); + $I->seeNodeCssStyle($last, 'width: 20%'); + + $html = TbHtml::stackedProgressBar(array()); + $this->assertEquals('', $html); + } + + public function testMediaList() + { + $I = $this->codeGuy; + + $items = array( + array('image' => 'image.png', 'heading' => 'Media heading', 'content' => 'Content text'), + array('heading' => 'Media heading', 'content' => 'Content text'), + ); + + $html = TbHtml::mediaList( + $items, + array( + 'class' => 'list', + ) + ); + $ul = $I->createNode($html, 'ul.media-list'); + $I->seeNodeNumChildren($ul, 2); + $I->seeNodeChildren($ul, array('li.media', 'li.media')); + + $html = TbHtml::mediaList(array()); + $this->assertEquals('', $html); + } + + public function testMedias() + { + $I = $this->codeGuy; + + $items = array( + array( + 'image' => 'image.png', + 'heading' => 'Media heading', + 'content' => 'Content text', + 'items' => array( + array( + 'image' => '#', + 'heading' => 'Media heading', + 'content' => 'Content text', + ), + array( + 'image' => '#', + 'heading' => 'Media heading', + 'content' => 'Content text', + 'visible' => false, + ), + ) + ), + array('heading' => 'Media heading', 'content' => 'Content text'), + ); + + $html = TbHtml::medias($items); + $body = $I->createNode($html, 'body'); + $medias = $body->filter('div.media'); + $first = $medias->first(); + $I->seeNodeChildren($first, array('a.pull-left', 'div.media-body')); + $img = $first->filter('img.media-object'); + $I->seeNodeAttribute($img, 'src', 'image.png'); + $mediaBody = $first->filter('div.media-body'); + $I->seeNodeChildren($mediaBody, array('h4.media-heading', 'div.media')); + $I->seeNodeText($mediaBody, 'Content text'); + $h4 = $body->filter('h4.media-heading'); + $I->seeNodeText($h4, 'Media heading'); + $I->seeNodeNumChildren($mediaBody, 1, 'div.media'); + $last = $medias->last(); + $I->seeNodeChildren($last, array('div.media-body')); + + $html = TbHtml::medias(array()); + $this->assertEquals('', $html); + } + + public function testMedia() + { + $I = $this->codeGuy; + + $html = TbHtml::media( + 'image.png', + 'Heading text', + 'Content text', + array( + 'class' => 'div', + 'linkOptions' => array('class' => 'link'), + 'imageOptions' => array('class' => 'image', 'alt' => 'Alternative text'), + 'contentOptions' => array('class' => 'content'), + 'headingOptions' => array('class' => 'heading'), + ) + ); + $div = $I->createNode($html, 'div.media'); + $I->seeNodeCssClass($div, 'div'); + $I->seeNodeChildren($div, array('a.pull-left', 'div.media-body')); + $a = $div->filter('a.pull-left'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + $img = $a->filter('img.media-object'); + $I->seeNodeCssClass($img, 'image'); + $I->seeNodeAttributes( + $img, + array( + 'src' => 'image.png', + 'alt' => 'Alternative text', + ) + ); + $content = $div->filter('div.media-body'); + $I->seeNodeCssClass($content, 'content'); + $I->seeNodeText($content, 'Content text'); + $h4 = $content->filter('h4.media-heading'); + $I->seeNodeCssClass($h4, 'heading'); + $I->seeNodeText($h4, 'Heading text'); + } + + public function testWell() + { + $I = $this->codeGuy; + $html = TbHtml::well( + 'Well text', + array( + 'class' => 'div', + 'size' => TbHtml::WELL_SIZE_LARGE, + ) + ); + $well = $I->createNode($html, 'div.well'); + $I->seeNodeCssClass($well, 'well-large'); + $I->seeNodeText($well, 'Well text'); + } + + public function testCloseLink() + { + $I = $this->codeGuy; + $html = TbHtml::closeLink( + 'Close', + '#', + array( + 'class' => 'link', + 'dismiss' => TbHtml::CLOSE_DISMISS_ALERT, + ) + ); + $a = $I->createNode($html, 'a[type=button].close'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'data-dismiss' => 'alert', + ) + ); + $I->seeNodeText($a, 'Close'); + } + + public function testCloseButton() + { + $I = $this->codeGuy; + $html = TbHtml::closeButton( + 'Close', + array( + 'dismiss' => TbHtml::CLOSE_DISMISS_MODAL, + 'class' => 'button', + ) + ); + $button = $I->createNode($html, 'button[type=button].close'); + $I->seeNodeCssClass($button, 'button'); + $I->seeNodeAttribute($button, 'data-dismiss', 'modal'); + $I->seeNodeText($button, 'Close'); + } + + + public function testCollapseLink() + { + $I = $this->codeGuy; + $html = TbHtml::collapseLink( + 'Link', + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a[data-toggle=collapse]'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttribute($a, 'href', '#'); + $I->seeNodeText($a, 'Link'); + } + + public function testTooltip() + { + $I = $this->codeGuy; + + $html = TbHtml::tooltip( + 'Link', + '#', + 'Tooltip text', + array( + 'class' => 'link', + 'animation' => true, + 'html' => true, + 'selector' => '.selector', + 'placement' => TbHtml::TOOLTIP_PLACEMENT_RIGHT, + 'trigger' => TbHtml::TOOLTIP_TRIGGER_CLICK, + 'delay' => 350, + ) + ); + $a = $I->createNode($html, 'a[rel=tooltip]'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'title' => 'Tooltip text', + 'data-animation' => 'true', + 'data-html' => 'true', + 'data-selector' => '.selector', + 'data-placement' => 'right', + 'data-trigger' => 'click', + 'data-delay' => '350', + 'href' => '#' + ) + ); + $I->seeNodeText($a, 'Link'); + } + + public function testPopover() + { + $I = $this->codeGuy; + + $html = TbHtml::popover( + 'Link', + 'Heading text', + 'Content text', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a[rel=popover]'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'title' => 'Heading text', + 'data-content' => 'Content text', + 'data-toggle' => 'popover', + 'href' => '#' + ) + ); + $I->seeNodeText($a, 'Link'); + } + + public function testCarousel() + { + $I = $this->codeGuy; + + $items = array( + array( + 'image' => 'image.png', + 'label' => 'First Thumbnail label', + 'url' => '#', + 'caption' => 'Caption text', + ), + array('image' => 'image.png', 'label' => 'Second Thumbnail label'), + array('image' => 'image.png', 'imageOptions' => array('class' => 'image', 'alt' => 'Alternative text')), + ); + + $html = TbHtml::carousel( + $items, + array( + 'id' => 'carousel', + 'class' => 'div', + ) + ); + $carousel = $I->createNode($html, 'div.carousel'); + $I->seeNodeCssClass($carousel, 'div slide'); + $I->seeNodeAttribute($carousel, 'carousel'); + $I->seeNodeChildren($carousel, array('ol.carousel-indicators', 'div.carousel-inner', 'a.carousel-control', 'a.carousel-control')); + $inner = $carousel->filter('div.carousel-inner'); + foreach ($inner->children() as $i => $divElement) { + $div = $I->createNode($divElement); + $I->seeNodeCssClass($div, 'item'); + switch ($i) { + case 0: + $I->seeNodeCssClass($div, 'active'); + $I->seeNodeChildren($div, array('a', 'div.carousel-caption')); + $a = $div->filter('a'); + $I->seeNodeAttribute($a, 'href', '#'); + break; + case 1: + $I->seeNodeChildren($div, array('img', 'div.carousel-caption')); + break; + case 2: + $img = $div->filter('img.image'); + $I->seeNodeAttributes( + $img, + array( + 'src' => 'image.png', + 'alt' => 'Alternative text', + ) + ); + break; + } + } + } + + public function testCarouselItem() + { + $I = $this->codeGuy; + $html = TbHtml::carouselItem( + 'Content text', + 'Label text', + 'Caption text', + array( + 'class' => 'div', + 'overlayOptions' => array('class' => 'overlay'), + 'labelOptions' => array('class' => 'label'), + 'captionOptions' => array('class' => 'caption'), + ) + ); + $div = $I->createNode($html, 'div.item'); + $I->seeNodeCssClass($div, 'div'); + $I->seeNodeText($div, 'Content text'); + $overlay = $div->filter('div.carousel-caption'); + $I->seeNodeCssClass($overlay, 'overlay'); + $I->seeNodeChildren($overlay, array('h4', 'p')); + $h4 = $overlay->filter('h4'); + $I->seeNodeCssClass($h4, 'label'); + $caption = $overlay->filter('p'); + $I->seeNodeCssClass($caption, 'caption'); + $I->seeNodeText($caption, 'Caption text'); + } + + public function testCarouselPrevLink() + { + $I = $this->codeGuy; + $html = TbHtml::carouselPrevLink( + 'Previous', + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.carousel-control.left'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'data-slide' => 'prev', + ) + ); + $I->seeNodeText($a, 'Previous'); + } + + public function testCarouselNextLink() + { + $I = $this->codeGuy; + $html = TbHtml::carouselNextLink( + 'Next', + '#', + array( + 'class' => 'link', + ) + ); + $a = $I->createNode($html, 'a.carousel-control.right'); + $I->seeNodeCssClass($a, 'link'); + $I->seeNodeAttributes( + $a, + array( + 'href' => '#', + 'data-slide' => 'next', + ) + ); + $I->seeNodeText($a, 'Next'); + } + + public function testCarouselIndicators() + { + $I = $this->codeGuy; + $html = TbHtml::carouselIndicators( + '#', + 3, + array( + 'class' => 'list', + ) + ); + $ol = $I->createNode($html, 'ol.carousel-indicators'); + $I->seeNodeCssClass($ol, 'list'); + $I->seeNodeChildren($ol, array('li.active', 'li', 'li')); + foreach ($ol->filter('li') as $i => $element) { + $node = $I->createNode($element); + $I->seeNodeAttributes( + $node, + array( + 'data-target' => '#', + 'data-slide-to' => $i, + ) + ); + $I->seeNodeEmpty($node); + } + } + + public function testAddCssClass() + { + $htmlOptions = array('class' => 'my'); + TbHtml::addCssClass(array('class'), $htmlOptions); + $this->assertEquals('my class', $htmlOptions['class']); + TbHtml::addCssClass('more classes', $htmlOptions); + $this->assertEquals('my class more classes', $htmlOptions['class']); + TbHtml::addCssClass(array('my'), $htmlOptions); + $this->assertEquals('my class more classes', $htmlOptions['class']); + TbHtml::addCssClass('class more classes', $htmlOptions); + $this->assertEquals('my class more classes', $htmlOptions['class']); + } + + public function testAddCssStyle() + { + $htmlOptions = array('style' => 'display: none'); + TbHtml::addCssStyle('color: purple', $htmlOptions); + TbHtml::addCssStyle('background: #fff;', $htmlOptions); + TbHtml::addCssStyle(array('font-family: "Open sans"', 'font-weight: bold;'), $htmlOptions); + $this->assertEquals( + 'display: none; color: purple; background: #fff; font-family: "Open sans"; font-weight: bold', + $htmlOptions['style'] + ); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/tests/unit/TbTestCase.php b/www/protected/extensions/bootstrap/tests/unit/TbTestCase.php new file mode 100644 index 0000000..54475fb --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/unit/TbTestCase.php @@ -0,0 +1,69 @@ +destroyApplication(); + } + + /** + * @param array $config + * @param string $appClass + */ + protected function mockApplication($config = array(), $appClass = 'TestApplication') + { + $defaultConfig = array( + 'basePath' => __DIR__, + 'aliases' => array( + 'bootstrap' => __DIR__ . '/../..', + ), + ); + Yii::createApplication( + $appClass, + CMap::mergeArray($defaultConfig, $config) + ); + } + + /** + * + */ + protected function destroyApplication() + { + Yii::setApplication(null); + } + + /** + * @param $widgetClass + * @param array $properties + * @return string + */ + protected function runWidget($widgetClass, $properties = array()) + { + return $this->mockController()->widget($widgetClass, $properties, true); + } + + /** + * @param $widgetClass + * @param array $properties + * @return CWidget + */ + protected function beginWidget($widgetClass, $properties = array()) + { + return $this->mockController()->beginWidget($widgetClass, $properties); + } + + /** + * @return CController + */ + private function mockController() + { + return new CController('dummy'); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/tests/unit/_bootstrap.php b/www/protected/extensions/bootstrap/tests/unit/_bootstrap.php new file mode 100644 index 0000000..7dfa7c3 --- /dev/null +++ b/www/protected/extensions/bootstrap/tests/unit/_bootstrap.php @@ -0,0 +1,2 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap active form widget. + */ +class TbActiveForm extends CActiveForm +{ + /** + * @var string the form layout. + */ + public $layout; + /** + * @var string the help type. Valid values are TbHtml::HELP_INLINE and TbHtml::HELP_BLOCK. + */ + public $helpType = TbHtml::HELP_TYPE_BLOCK; + /** + * @var string the CSS class name for error messages. + */ + public $errorMessageCssClass = 'error'; + /** + * @var string the CSS class name for success messages. + */ + public $successMessageCssClass = 'success'; + + /** + * @var boolean whether to hide inline errors. Defaults to false. + */ + public $hideInlineErrors = false; + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + if ($this->stateful) { + echo TbHtml::statefulFormTb($this->layout, $this->action, $this->method, $this->htmlOptions); + } else { + echo TbHtml::beginFormTb($this->layout, $this->action, $this->method, $this->htmlOptions); + } + } + + /** + * Displays the first validation error for a model attribute. + * @param CModel $model the data model + * @param string $attribute the attribute name + * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag. + * @param boolean $enableAjaxValidation whether to enable AJAX validation for the specified attribute. + * @param boolean $enableClientValidation whether to enable client-side validation for the specified attribute. + * @return string the validation result (error display or success message). + */ + public function error( + $model, + $attribute, + $htmlOptions = array(), + $enableAjaxValidation = true, + $enableClientValidation = true + ) { + if (!$this->enableAjaxValidation) { + $enableAjaxValidation = false; + } + if (!$this->enableClientValidation) { + $enableClientValidation = false; + } + if (!$enableAjaxValidation && !$enableClientValidation) { + return TbHtml::error($model, $attribute, $htmlOptions); + } + $id = CHtml::activeId($model, $attribute); + $inputID = TbArray::getValue('inputID', $htmlOptions, $id); + unset($htmlOptions['inputID']); + TbArray::defaultValue('id', $inputID . '_em_', $htmlOptions); + $option = array( + 'id' => $id, + 'inputID' => $inputID, + 'errorID' => $htmlOptions['id'], + 'model' => get_class($model), + 'name' => $attribute, + 'enableAjaxValidation' => $enableAjaxValidation, + 'inputContainer' => 'div.control-group', // Bootstrap requires this + ); + $optionNames = array( + 'validationDelay', + 'validateOnChange', + 'validateOnType', + 'hideErrorMessage', + 'inputContainer', + 'errorCssClass', + 'successCssClass', + 'validatingCssClass', + 'beforeValidateAttribute', + 'afterValidateAttribute', + ); + foreach ($optionNames as $name) { + if (isset($htmlOptions[$name])) { + $option[$name] = TbArray::popValue($name, $htmlOptions); + } + } + if ($model instanceof CActiveRecord && !$model->isNewRecord) { + $option['status'] = 1; + } + if ($enableClientValidation) { + $validators = TbArray::getValue('clientValidation', $htmlOptions, array()); + $attributeName = $attribute; + if (($pos = strrpos($attribute, ']')) !== false && $pos !== strlen($attribute) - 1) // e.g. [a]name + { + $attributeName = substr($attribute, $pos + 1); + } + foreach ($model->getValidators($attributeName) as $validator) { + if ($validator->enableClientValidation) { + if (($js = $validator->clientValidateAttribute($model, $attributeName)) != '') { + $validators[] = $js; + } + } + } + if ($validators !== array()) { + $option['clientValidation'] = "js:function(value, messages, attribute) {\n" . implode( + "\n", + $validators + ) . "\n}"; + } + } + $html = TbHtml::error($model, $attribute, $htmlOptions); + if ($html === '') { + $htmlOptions['type'] = $this->helpType; + TbHtml::addCssStyle('display:none', $htmlOptions); + $html = TbHtml::help('', $htmlOptions); + } + $this->attributes[$inputID] = $option; + return $html; + } + + /** + * Displays a summary of validation errors for one or several models. + * @param mixed $models the models whose input errors are to be displayed. + * @param string $header a piece of HTML code that appears in front of the errors + * @param string $footer a piece of HTML code that appears at the end of the errors + * @param array $htmlOptions additional HTML attributes to be rendered in the container div tag. + * @return string the error summary. Empty if no errors are found. + */ + public function errorSummary($models, $header = null, $footer = null, $htmlOptions = array()) + { + if (!$this->enableAjaxValidation && !$this->enableClientValidation) { + return TbHtml::errorSummary($models, $header, $footer, $htmlOptions); + } + TbArray::defaultValue('id', $this->id . '_es_', $htmlOptions); + $html = TbHtml::errorSummary($models, $header, $footer, $htmlOptions); + if ($html === '') { + if ($header === null) { + $header = '

' . Yii::t('yii', 'Please fix the following input errors:') . '

'; + } + TbHtml::addCssClass(TbHtml::$errorSummaryCss, $htmlOptions); + TbHtml::addCssStyle('display:none', $htmlOptions); + $html = CHtml::tag('div', $htmlOptions, $header . '' . $footer); + } + $this->summaryID = $htmlOptions['id']; + return $html; + } + + /** + * Generates a text field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + * @see TbHtml::activeTextField + */ + public function textField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_TEXT, $model, $attribute, $htmlOptions); + } + + /** + * Generates a password field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + * @see TbHtml::activePasswordField + */ + public function passwordField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_PASSWORD, $model, $attribute, $htmlOptions); + } + + /** + * Generates an url field for a model attribute. + * @param CModel $model the data model + * @param string $attribute the attribute + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field + * @see TbHtml::activeUrlField + */ + public function urlField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_URL, $model, $attribute, $htmlOptions); + } + + /** + * Generates an email field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + * @see TbHtml::activeEmailField + */ + public function emailField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_EMAIL, $model, $attribute, $htmlOptions); + } + + /** + * Generates a number field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + * @see TbHtml::activeNumberField + */ + public function numberField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_NUMBER, $model, $attribute, $htmlOptions); + } + + /** + * Generates a range field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + * @see TbHtml::activeRangeField + */ + public function rangeField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_RANGE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a date field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input field. + */ + public function dateField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_DATE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a text area for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated text area. + * @see TbHtml::activeTextArea + */ + public function textArea($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_TEXTAREA, $model, $attribute, $htmlOptions); + } + + /** + * Generates a file field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes + * @return string the generated input field. + * @see TbHtml::activeFileField + */ + public function fileField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_FILE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a radio button for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated radio button. + * @see TbHtml::activeRadioButton + */ + public function radioButton($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTON, $model, $attribute, $htmlOptions); + } + + /** + * Generates a checkbox for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated check box. + * @see TbHtml::activeCheckBox + */ + public function checkBox($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOX, $model, $attribute, $htmlOptions); + } + + /** + * Generates a dropdown list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated drop down list. + * @see TbHtml::activeDropDownList + */ + public function dropDownList($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_DROPDOWNLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a list box for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated list box. + * @see TbHtml::activeListBox + */ + public function listBox($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_LISTBOX, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a radio button list for a model attribute + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display) + * @param array $htmlOptions additional HTML attributes. + * @return string the generated radio button list. + * @see TbHtml::activeRadioButtonList + */ + public function radioButtonList($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates an inline radio button list for a model attribute + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display) + * @param array $htmlOptions additional HTML attributes. + * @return string the generated radio button list. + * @see TbHtml::activeInlineRadioButtonList + */ + public function inlineRadioButtonList($model, $attribute, $data, $htmlOptions = array()) + { + $htmlOptions['inline'] = true; + return $this->createInput(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a checkbox list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display) + * @param array $htmlOptions additional HTML attributes. + * @return string the generated checkbox list. + * @see TbHtml::activeCheckBoxList + */ + public function checkBoxList($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates an inline checkbox list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $data data for generating the list options (value=>display) + * @param array $htmlOptions additional HTML attributes. + * @return string the generated checkbox list. + * @see TbHtml::activeInlineCheckBoxList + */ + public function inlineCheckBoxList($model, $attribute, $data, $htmlOptions = array()) + { + $htmlOptions['inline'] = true; + return $this->createInput(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates an uneditable field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated field. + * @see TbHtml::activeUneditableField + */ + public function uneditableField($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_UNEDITABLE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a search query field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated input. + * @see TbHtml::activeSearchField + */ + public function searchQuery($model, $attribute, $htmlOptions = array()) + { + return $this->createInput(TbHtml::INPUT_TYPE_SEARCH, $model, $attribute, $htmlOptions); + } + + /** + * Generates an input for a model attribute. + * @param string $type the input type. + * @param CModel $model the data model. + * @param string $attribute the attribute. + * @param array $htmlOptions additional HTML attributes. + * @param array $data data for generating the list options (value=>display). + * @return string the generated input. + * @see TbHtml::createActiveInput + */ + public function createInput($type, $model, $attribute, $htmlOptions = array(), $data = array()) + { + return TbHtml::createActiveInput($type, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with a text field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeTextFieldControlGroup + */ + public function textFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_TEXT, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a password field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activePasswordFieldControlGroup + */ + public function passwordFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_PASSWORD, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with an url field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeUrlFieldControlGroup + */ + public function urlFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_URL, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with an email field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeEmailFieldControlGroup + */ + public function emailFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_EMAIL, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a number field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeNumberFieldControlGroup + */ + public function numberFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_NUMBER, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a range field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeRangeFieldControlGroup + */ + public function rangeFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_RANGE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a date field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeDateFieldControlGroup + */ + public function dateFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_DATE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a text area for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeTextAreaControlGroup + */ + public function textAreaControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_TEXTAREA, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a check box for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeCheckBoxControlGroup + */ + public function checkBoxControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOX, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a radio button for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeRadioButtonControlGroup + */ + public function radioButtonControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTON, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a drop down list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeDropDownListControlGroup + */ + public function dropDownListControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_DROPDOWNLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with a list box for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeListBoxControlGroup + */ + public function listBoxControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_LISTBOX, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with a file field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeFileFieldControlGroup + */ + public function fileFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_FILE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a radio button list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeRadioButtonListControlGroup + */ + public function radioButtonListControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with an inline radio button list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeInlineCheckBoxListControlGroup + */ + public function inlineRadioButtonListControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + $htmlOptions['inline'] = true; + return $this->createControlGroup(TbHtml::INPUT_TYPE_RADIOBUTTONLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with a check box list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeCheckBoxListControlGroup + */ + public function checkBoxListControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with an inline check box list for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $data data for generating the list options (value=>display). + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeInlineCheckBoxListControlGroup + */ + public function inlineCheckBoxListControlGroup($model, $attribute, $data, $htmlOptions = array()) + { + $htmlOptions['inline'] = true; + return $this->createControlGroup(TbHtml::INPUT_TYPE_CHECKBOXLIST, $model, $attribute, $htmlOptions, $data); + } + + /** + * Generates a control group with an uneditable field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeUneditableFieldControlGroup + */ + public function uneditableFieldControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_UNEDITABLE, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group with a search field for a model attribute. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @return string the generated control group. + * @see TbHtml::activeSearchFieldControlGroup + */ + public function searchQueryControlGroup($model, $attribute, $htmlOptions = array()) + { + return $this->createControlGroup(TbHtml::INPUT_TYPE_SEARCH, $model, $attribute, $htmlOptions); + } + + /** + * Generates a control group for a model attribute. + * @param string $type the input type. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $htmlOptions additional HTML attributes. + * @param array $data data for generating the list options (value=>display). + * @return string the generated control group. + * @see TbHtml::activeControlGroup + */ + public function createControlGroup($type, $model, $attribute, $htmlOptions = array(), $data = array()) + { + $htmlOptions = $this->processControlGroupOptions($model, $attribute, $htmlOptions); + return TbHtml::activeControlGroup($type, $model, $attribute, $htmlOptions, $data); + } + + /** + * Processes the options for a input row. + * @param CModel $model the data model. + * @param string $attribute the attribute name. + * @param array $options the options. + * @return array the processed options. + */ + protected function processControlGroupOptions($model, $attribute, $options) + { + $errorOptions = TbArray::popValue('errorOptions', $options, array()); + $enableAjaxValidation = TbArray::popValue('enableAjaxValidation', $errorOptions, true); + $enableClientValidation = TbArray::popValue('enableClientValidation', $errorOptions, true); + $errorOptions['type'] = $this->helpType; + $error = $this->error($model, $attribute, $errorOptions, $enableAjaxValidation, $enableClientValidation); + // kind of a hack for ajax forms but this works for now. + if (!empty($error) && strpos($error, 'display:none') === false) { + $options['color'] = TbHtml::INPUT_COLOR_ERROR; + } + if (!$this->hideInlineErrors) { + $options['error'] = $error; + } + $helpOptions = TbArray::popValue('helpOptions', $options, array()); + $helpOptions['type'] = $this->helpType; + $options['helpOptions'] = $helpOptions; + return $options; + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbAffix.php b/www/protected/extensions/bootstrap/widgets/TbAffix.php new file mode 100644 index 0000000..837bccf --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbAffix.php @@ -0,0 +1,57 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap affix widget. + * @see http://twitter.github.com/bootstrap/javascript.html#affix + */ +class TbAffix extends CWidget +{ + /** + * @var string the HTML tag for the container. + */ + public $tagName = 'div'; + /** + * @var mixed pixels to offset from screen when calculating position of scroll. + */ + public $offset; + /** + * @var array the HTML attributes for the container. + */ + public $htmlOptions = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + $this->htmlOptions['data-spy'] = 'affix'; + if (isset($this->offset)) { + if (is_string($this->offset)) { + $this->offset = array('top', $this->offset); + } + + if (is_array($this->offset) && count($this->offset) === 2) { + list($position, $offset) = $this->offset; + $this->htmlOptions['data-offset-' . $position] = $offset; + } + } + echo TbHtml::openTag($this->tagName, $this->htmlOptions); + } + + /** + * Runs the widget. + */ + public function run() + { + echo CHtml::closeTag($this->tagName); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbAlert.php b/www/protected/extensions/bootstrap/widgets/TbAlert.php new file mode 100644 index 0000000..0dcac64 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbAlert.php @@ -0,0 +1,95 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap alert widget. + * @see http://twitter.github.com/bootstrap/javascript.html#alerts + */ +class TbAlert extends CWidget +{ + /** + * @var array the alerts configurations (style=>config). + */ + public $alerts; + /** + * @var string|boolean the close link text. If this is set false, no close link will be displayed. + */ + public $closeText = TbHtml::CLOSE_TEXT; + /** + * @var boolean indicates whether the alert should be an alert block. Defaults to 'true'. + */ + public $block = true; + /** + * @var boolean indicates whether alerts should use transitions. Defaults to 'true'. + */ + public $fade = true; + /** + * @var string[] the JavaScript event configuration (name=>handler). + */ + public $events = array(); + /** + * @var array the HTML attributes for the alert container. + */ + public $htmlOptions = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + if (is_string($this->alerts)) { + $colors = explode(' ', $this->alerts); + } else { + if (!isset($this->alerts)) { + $colors = array( + TbHtml::ALERT_COLOR_SUCCESS, + TbHtml::ALERT_COLOR_WARNING, + TbHtml::ALERT_COLOR_INFO, + TbHtml::ALERT_COLOR_ERROR + ); // render all styles by default + } + } + if (isset($colors)) { + $this->alerts = array(); + foreach ($colors as $color) { + $this->alerts[$color] = array(); + } + } + } + + /** + * Runs the widget. + */ + public function run() + { + /* @var $user CWebUser */ + $user = Yii::app()->getUser(); + if (count($user->getFlashes(false)) == 0) { + return; + } + echo TbHtml::openTag('div', $this->htmlOptions); + foreach ($this->alerts as $color => $alert) { + if (isset($alert['visible']) && !$alert['visible']) { + continue; + } + + if ($user->hasFlash($color)) { + $htmlOptions = TbArray::popValue('htmlOptions', $alert, array()); + TbArray::defaultValue('closeText', $this->closeText, $htmlOptions); + TbArray::defaultValue('block', $this->block, $htmlOptions); + TbArray::defaultValue('fade', $this->fade, $htmlOptions); + echo TbHtml::alert($color, $user->getFlash($color), $htmlOptions); + } + } + echo ''; + $this->registerEvents("#{$this->htmlOptions['id']} > .alert", $this->events); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbBreadcrumb.php b/www/protected/extensions/bootstrap/widgets/TbBreadcrumb.php new file mode 100644 index 0000000..7a52619 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbBreadcrumb.php @@ -0,0 +1,74 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + */ + +/** + * Bootstrap breadcrumb widget. + * @see http://twitter.github.com/bootstrap/components.html#breadcrumbs + * @package bootstrap.widgets + */ +class TbBreadcrumb extends CWidget +{ + /** + * @var string the divider between links in the breadcrumbs. + */ + public $divider = '/'; + /** + * @var boolean whether to HTML encode the link labels. + */ + public $encodeLabel = true; + /** + * @var string the label for the first link in the breadcrumb. + */ + public $homeLabel; + /** + * @var array the url for the first link in the breadcrumb + */ + public $homeUrl; + /** + * @var array the HTML attributes for the breadcrumbs. + */ + public $htmlOptions = array(); + /** + * @var array list of links to appear in the breadcrumbs. + */ + public $links = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->htmlOptions['divider'] = $this->divider; + } + + /** + * Runs the widget. + */ + public function run() + { + // todo: consider adding control property for displaying breadcrumbs even when empty. + if (!empty($this->links)) { + $links = array(); + if ($this->homeLabel !== false) { + $label = $this->homeLabel !== null ? $this->homeLabel : TbHtml::icon('home'); + $links[$label] = $this->homeUrl !== null ? $this->homeUrl : Yii::app()->homeUrl; + } + foreach ($this->links as $label => $url) { + if (is_string($label)) { + if ($this->encodeLabel) { + $label = CHtml::encode($label); + } + $links[$label] = $url; + } else { + $links[] = $this->encodeLabel ? CHtml::encode($url) : $url; + } + } + echo TbHtml::breadcrumbs($links, $this->htmlOptions); + } + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbButtonColumn.php b/www/protected/extensions/bootstrap/widgets/TbButtonColumn.php new file mode 100644 index 0000000..c427dff --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbButtonColumn.php @@ -0,0 +1,88 @@ + + * @author Christoffer Niska + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +Yii::import('zii.widgets.grid.CButtonColumn'); + +/** + * Bootstrap button column widget. + */ +class TbButtonColumn extends CButtonColumn +{ + /** + * @var string the view button icon (defaults to TbHtml::ICON_EYE_OPEN). + */ + public $viewButtonIcon = TbHtml::ICON_EYE_OPEN; + /** + * @var string the update button icon (defaults to TbHtml::ICON_PENCIL). + */ + public $updateButtonIcon = TbHtml::ICON_PENCIL; + /** + * @var string the delete button icon (defaults to TbHtml::ICON_TRASH). + */ + public $deleteButtonIcon = TbHtml::ICON_TRASH; + + /** + * Initializes the default buttons (view, update and delete). + */ + protected function initDefaultButtons() + { + parent::initDefaultButtons(); + + if ($this->viewButtonIcon !== false && !isset($this->buttons['view']['icon'])) { + $this->buttons['view']['icon'] = $this->viewButtonIcon; + } + if ($this->updateButtonIcon !== false && !isset($this->buttons['update']['icon'])) { + $this->buttons['update']['icon'] = $this->updateButtonIcon; + } + if ($this->deleteButtonIcon !== false && !isset($this->buttons['delete']['icon'])) { + $this->buttons['delete']['icon'] = $this->deleteButtonIcon; + } + } + + /** + * Renders a link button. + * @param string $id the ID of the button + * @param array $button the button configuration which may contain 'label', 'url', 'imageUrl' and 'options' elements. + * @param integer $row the row number (zero-based) + * @param mixed $data the data object associated with the row + */ + protected function renderButton($id, $button, $row, $data) + { + if (isset($button['visible']) && !$this->evaluateExpression( + $button['visible'], + array('row' => $row, 'data' => $data) + ) + ) { + return; + } + + $url = TbArray::popValue('url', $button); + if ($url !== '#') { + $url = $this->evaluateExpression($url, array('data' => $data, 'row' => $row)); + } + + $imageUrl = TbArray::popValue('imageUrl', $button, false); + $label = TbArray::popValue('label', $button, $id); + $options = TbArray::popValue('options', $button, array()); + + TbArray::defaultValue('title', $label, $options); + TbArray::defaultValue('rel', 'tooltip', $options); + + if ($icon = TbArray::popValue('icon', $button, false)) { + echo CHtml::link(TbHtml::icon($icon), $url, $options); + } else { + if ($imageUrl && is_string($imageUrl)) { + echo CHtml::link(CHtml::image($imageUrl, $label), $url, $options); + } else { + echo CHtml::link($label, $url, $options); + } + } + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbCollapse.php b/www/protected/extensions/bootstrap/widgets/TbCollapse.php new file mode 100644 index 0000000..afc6b0b --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbCollapse.php @@ -0,0 +1,82 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap collapse widget. + * @see http://twitter.github.com/bootstrap/javascript.html#collapse + */ +class TbCollapse extends CWidget +{ + /** + * @var string the HTML tag for the container. + */ + public $tagName = 'div'; + /** + * @var string the content text. + */ + public $content; + /** + * @var string the path to a partial view. + */ + public $view; + /** + * @var string the CSS selector for the parent element. + */ + public $parent; + /** + * @var boolean whether to be collapsed on invocation. + */ + public $toggle; + /** + * @var string[] $events the JavaScript event configuration (name=>handler). + */ + public $events = array(); + /** + * @var array the HTML attributes for the container. + */ + public $htmlOptions = array(); + /** + * @var array additional data to be passed to the view. + */ + public $viewData = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + TbHtml::addCssClass('collapse', $this->htmlOptions); + if (isset($this->parent)) { + TbArray::defaultValue('data-parent', $this->parent, $this->htmlOptions); + } + if (isset($this->toggle) && $this->toggle) { + TbHtml::addCssClass('in', $this->htmlOptions); + } + if (isset($this->view)) { + $controller = $this->getController(); + if (isset($controller) && $controller->getViewFile($this->view) !== false) { + $this->content = $this->controller->renderPartial($this->view, $this->viewData, true); + } + } + echo TbHtml::openTag($this->tagName, $this->htmlOptions); + echo $this->content; + } + + /** + * Runs the widget. + */ + public function run() + { + echo CHtml::closeTag($this->tagName); + $selector = '#' . $this->htmlOptions['id']; + $this->registerEvents($selector, $this->events); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbDataColumn.php b/www/protected/extensions/bootstrap/widgets/TbDataColumn.php new file mode 100644 index 0000000..08a398c --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbDataColumn.php @@ -0,0 +1,103 @@ + + * @author Christoffer Niska + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +Yii::import('zii.widgets.grid.CDataColumn'); + +/** + * Bootstrap grid data column. + */ +class TbDataColumn extends CDataColumn +{ + /** + * @var array HTML options for filter input + * @link {TbDataColumn::renderFilterCellContent()} + */ + public $filterInputOptions; + + /** + * Renders the header cell content. + * This method will render a link that can trigger the sorting if the column is sortable. + */ + protected function renderHeaderCellContent() + { + if ($this->grid->enableSorting && $this->sortable && $this->name !== null) { + $sort = $this->grid->dataProvider->getSort(); + $label = isset($this->header) ? $this->header : $sort->resolveLabel($this->name); + + if ($sort->resolveAttribute($this->name) !== false) { + $label .= ''; + } + + echo $sort->link($this->name, $label, array('class' => 'sort-link')); + } else { + if ($this->name !== null && $this->header === null) { + if ($this->grid->dataProvider instanceof CActiveDataProvider) { + echo CHtml::encode($this->grid->dataProvider->model->getAttributeLabel($this->name)); + } else { + echo CHtml::encode($this->name); + } + } else { + parent::renderHeaderCellContent(); + } + } + } + + /** + * Renders the filter cell. + */ + public function renderFilterCell() + { + echo CHtml::openTag('td', $this->filterHtmlOptions); + echo '
'; + $this->renderFilterCellContent(); + echo '
'; + echo CHtml::closeTag('td'); + } + + /** + * Renders the filter cell content. Here we can provide HTML options for actual filter input + */ + protected function renderFilterCellContent() + { + if (is_string($this->filter)) { + echo $this->filter; + } else { + if ($this->filter !== false && $this->grid->filter !== null && $this->name !== null && strpos( + $this->name, + '.' + ) === false + ) { + if ($this->filterInputOptions) { + $filterInputOptions = $this->filterInputOptions; + if (empty($filterInputOptions['id'])) { + $filterInputOptions['id'] = false; + } + } else { + $filterInputOptions = array(); + } + if (is_array($this->filter)) { + $filterInputOptions['prompt'] = ''; + echo CHtml::activeDropDownList( + $this->grid->filter, + $this->name, + $this->filter, + $filterInputOptions + ); + } else { + if ($this->filter === null) { + echo CHtml::activeTextField($this->grid->filter, $this->name, $filterInputOptions); + } + } + } else { + parent::renderFilterCellContent(); + } + } + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbDetailView.php b/www/protected/extensions/bootstrap/widgets/TbDetailView.php new file mode 100644 index 0000000..698a8ad --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbDetailView.php @@ -0,0 +1,47 @@ + + * @author Christoffer Niska + * @copyright Copyright © Sam Stenvall 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ +Yii::import('zii.widgets.CDetailView'); + +/** + * Bootstrap Zii detail widget. + */ +class TbDetailView extends CDetailView +{ + /** + * @var string|array the detail view style. + * Valid values are TbHtml::DETAIL_STRIPED, TbHtml::DETAIL_BORDERED, TbHtml::DETAIL_CONDENSED and/or TbHtml::DETAIL_HOVER. + */ + public $type = array(TbHtml::DETAIL_TYPE_STRIPED, TbHtml::DETAIL_TYPE_CONDENSED); + /** + * @var string the URL of the CSS file used by this grid view. + * Defaults to false, meaning that no CSS will be included. + */ + public $cssFile = false; + + /** + * Initializes the widget. + */ + public function init() + { + parent::init(); + $classes = array('table'); + if (!empty($this->type)) { + if (is_string($this->type)) { + $this->type = explode(' ', $this->type); + } + + foreach ($this->type as $type) { + $classes[] = 'table-' . $type; + } + } + TbHtml::addCssClass($classes, $this->htmlOptions); + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbGridView.php b/www/protected/extensions/bootstrap/widgets/TbGridView.php new file mode 100644 index 0000000..74f7055 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbGridView.php @@ -0,0 +1,106 @@ + + * @author Christoffer Niska + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +Yii::import('zii.widgets.grid.CGridView'); + +/** + * Bootstrap Zii grid view. + */ +class TbGridView extends CGridView +{ + /** + * @var string|array the table style. + * Valid values are TbHtml::GRID_TYPE_STRIPED, TbHtml::GRID_TYPE_BORDERED, TbHtml::GRID_TYPE_CONDENSED and/or + * TbHtml::GRID_TYPE_HOVER. + */ + public $type; + /** + * @var string the CSS class name for the pager container. Defaults to 'pagination'. + */ + public $pagerCssClass = 'pagination'; + /** + * @var array the configuration for the pager. + * Defaults to array('class'=>'ext.bootstrap.widgets.TbPager'). + */ + public $pager = array('class' => 'bootstrap.widgets.TbPager'); + /** + * @var string the URL of the CSS file used by this grid view. + * Defaults to false, meaning that no CSS will be included. + */ + public $cssFile = false; + /** + * @var string the template to be used to control the layout of various sections in the view. + */ + public $template = "{items}\n
{pager}
{summary}
"; + + /** + * Initializes the widget. + */ + public function init() + { + parent::init(); + $classes = array('table'); + if (isset($this->type) && !empty($this->type)) { + if (is_string($this->type)) { + $this->type = explode(' ', $this->type); + } + + foreach ($this->type as $type) { + $classes[] = 'table-' . $type; + } + } + if (!empty($classes)) { + $classes = implode(' ', $classes); + if (isset($this->itemsCssClass)) { + $this->itemsCssClass .= ' ' . $classes; + } else { + $this->itemsCssClass = $classes; + } + } + } + + /** + * Creates column objects and initializes them. + */ + protected function initColumns() + { + foreach ($this->columns as $i => $column) { + if (is_array($column) && !isset($column['class'])) { + $this->columns[$i]['class'] = 'bootstrap.widgets.TbDataColumn'; + } + } + parent::initColumns(); + } + + /** + * Creates a column based on a shortcut column specification string. + * @param mixed $text the column specification string + * @return \TbDataColumn|\CDataColumn the column instance + * @throws CException if the column format is incorrect + */ + protected function createDataColumn($text) + { + if (!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/', $text, $matches)) { + throw new CException(Yii::t( + 'zii', + 'The column must be specified in the format of "Name:Type:Label", where "Type" and "Label" are optional.' + )); + } + $column = new TbDataColumn($this); + $column->name = $matches[1]; + if (isset($matches[3]) && $matches[3] !== '') { + $column->type = $matches[3]; + } + if (isset($matches[5])) { + $column->header = $matches[5]; + } + return $column; + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbHeroUnit.php b/www/protected/extensions/bootstrap/widgets/TbHeroUnit.php new file mode 100644 index 0000000..3660be5 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbHeroUnit.php @@ -0,0 +1,62 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap hero unit widget. + * @see http://twitter.github.com/bootstrap/javascript.html#affix + */ +class TbHeroUnit extends CWidget +{ + /** + * @var string the heading text. + */ + public $heading; + /** + * @var array the HTML attributes for the heading. + */ + public $headingOptions = array(); + /** + * @var string the content text. + */ + public $content; + /** + * @var string the path to a partial view. + */ + public $view; + /** + * @var array the HTML attributes for the container tag. + */ + public $htmlOptions = array(); + /** + * @var array additional data to be passed to the view. + */ + public $viewData = array(); + + /** + * Initializes the widget. + */ + public function init() + { + if (isset($this->view)) { + $controller = $this->getController(); + if (isset($controller) && $controller->getViewFile($this->view) !== false) { + $this->content = $this->controller->renderPartial($this->view, $this->viewData, true); + } + } + $this->htmlOptions['headingOptions'] = $this->headingOptions; + } + + /** + * Runs the widget. + */ + public function run() + { + echo TbHtml::heroUnit($this->heading, $this->content, $this->htmlOptions); + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbListView.php b/www/protected/extensions/bootstrap/widgets/TbListView.php new file mode 100644 index 0000000..a7f98dd --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbListView.php @@ -0,0 +1,44 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +Yii::import('zii.widgets.CListView'); + +/** + * Bootstrap Zii list view. + */ +class TbListView extends CListView +{ + /** + * @var string the CSS class name for the pager container. Defaults to 'pagination'. + */ + public $pagerCssClass = 'pagination'; + /** + * @var array the configuration for the pager. + * Defaults to array('class'=>'ext.bootstrap.widgets.TbPager'). + */ + public $pager = array('class' => 'bootstrap.widgets.TbPager'); + /** + * @var string the URL of the CSS file used by this detail view. + * Defaults to false, meaning that no CSS will be included. + */ + public $cssFile = false; + /** + * @var string the template to be used to control the layout of various sections in the view. + */ + public $template = "{items}\n
{pager}
{summary}
"; + + /** + * Renders the empty message when there is no data. + */ + public function renderEmptyText() + { + $emptyText = $this->emptyText === null ? Yii::t('zii', 'No results found.') : $this->emptyText; + echo TbHtml::tag('div', array('class' => 'empty', 'span' => 12), $emptyText); + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbModal.php b/www/protected/extensions/bootstrap/widgets/TbModal.php new file mode 100644 index 0000000..0dad704 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbModal.php @@ -0,0 +1,261 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap modal widget. + */ +class TbModal extends CWidget +{ + /** + * @var array the HTML options for the view container tag. + */ + public $htmlOptions = array(); + + /** + * @var array The additional HTML attributes of the button that will show the modal. If empty array, only + * the markup of the modal will be rendered on the page, so users can easily call the modal manually with their own + * scripts. The following special attributes are available: + *
    + *
  • label: string, the label of the button
  • + *
+ * + * For available options of the button trigger, see http://twitter.github.com/bootstrap/javascript.html#modals. + */ + public $buttonOptions = array(); + + /** + * @var boolean indicates whether the modal should use transitions. Defaults to 'true'. + */ + public $fade = true; + + /** + * @var bool $keyboard, closes the modal when escape key is pressed. + */ + public $keyboard = true; + + /** + * @var bool $show, shows the modal when initialized. + */ + public $show = false; + + /** + * @var mixed includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn't close + * the modal on click. + */ + public $backdrop = true; + + /** + * @var mixed the remote url. If a remote url is provided, content will be loaded via jQuery's load method and + * injected into the .modal-body of the modal. + */ + public $remote; + + /** + * @var string a javascript function that will be invoked immediately when the `show` instance method is called. + */ + public $onShow; + + /** + * @var string a javascript function that will be invoked when the modal has been made visible to the user + * (will wait for css transitions to complete). + */ + public $onShown; + + /** + * @var string a javascript function that will be invoked immediately when the hide instance method has been called. + */ + public $onHide; + + /** + * @var string a javascript function that will be invoked when the modal has finished being hidden from the user + * (will wait for css transitions to complete). + */ + public $onHidden; + + /** + * @var string[] the Javascript event handlers. + */ + protected $events = array(); + + /** + * @var array $options the plugin options. + */ + protected $options = array(); + + /** + * @var string + */ + public $closeText = TbHtml::CLOSE_TEXT; + + /** + * @var string header content + */ + public $header; + + /** + * @var string body of modal + */ + public $content; + + /** + * @var string footer content + */ + public $footer; + + /** + * Widget's initialization method + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + + TbArray::defaultValue('id', $this->getId(), $this->htmlOptions); + TbArray::defaultValue('role', 'dialog', $this->htmlOptions); + TbArray::defaultValue('tabindex', '-1', $this->htmlOptions); + + TbHtml::addCssClass('modal hide', $this->htmlOptions); + if ($this->fade) { + TbHtml::addCssClass('fade', $this->htmlOptions); + } + + if (is_array($this->footer)) { + $this->footer = implode(' ', $this->footer); + } + + $this->initOptions(); + $this->initEvents(); + } + + /** + * Initialize events if any + */ + public function initEvents() + { + foreach (array('onShow', 'onShown', 'onHide', 'onHidden') as $event) { + if ($this->$event !== null) { + $modalEvent = strtolower(substr($event, 2)); + if ($this->$event instanceof CJavaScriptExpression) { + $this->events[$modalEvent] = $this->$event; + } else { + $this->events[$modalEvent] = new CJavaScriptExpression($this->$event); + } + } + } + } + + /** + * Initialize plugin options. + * ***Important***: The display of the button overrides the initialization of the modal bootstrap widget. + */ + public function initOptions() + { + if ($remote = TbArray::popValue('remote', $this->options)) { + $this->options['remote'] = CHtml::normalizeUrl($remote); + } + + TbArray::defaultValue('backdrop', $this->backdrop, $this->options); + TbArray::defaultValue('keyboard', $this->keyboard, $this->options); + TbArray::defaultValue('show', $this->show, $this->options); + } + + /** + * Widget's run method + */ + public function run() + { + $this->renderModal(); + $this->renderButton(); + $this->registerClientScript(); + } + + /** + * Renders the button + */ + public function renderButton() + { + if (!empty($this->buttonOptions) && is_array($this->buttonOptions)) { + TbArray::defaultValue('data-toggle', 'modal', $this->buttonOptions); + + if ($this->remote !== null) { + $this->buttonOptions['data-remote'] = CHtml::normalizeUrl($this->remote); + } + + $selector = '#' . $this->htmlOptions['id']; + $label = TbArray::popValue('label', $this->buttonOptions, 'button'); + $attr = isset($this->buttonOptions['data-remote']) ? 'data-target' : 'href'; + TbArray::defaultValue($attr, $selector, $this->buttonOptions); + echo TbHtml::button($label, $this->buttonOptions); + } + } + + /** + * Renders the modal markup + */ + public function renderModal() + { + echo TbHtml::openTag('div', $this->htmlOptions) . PHP_EOL; + + $this->renderModalHeader(); + $this->renderModalBody(); + $this->renderModalFooter(); + + echo '' . PHP_EOL; + } + + /** + * Renders the header HTML markup of the modal + */ + public function renderModalHeader() + { + echo '' . PHP_EOL; + } + + /** + * Renders the HTML markup for the body of the modal + */ + public function renderModalBody() + { + echo '' . PHP_EOL; + } + + /** + * Renders the HTML markup for the footer of the modal + */ + public function renderModalFooter() + { + + echo '' . PHP_EOL; + } + + /** + * Registers necessary client scripts. + */ + public function registerClientScript() + { + $selector = '#' . $this->htmlOptions['id']; + + // do we render a button? If so, bootstrap will handle its behavior through its + // mark-up, otherwise, register the plugin. + if (empty($this->buttonOptions)) { + $this->registerPlugin(TbApi::PLUGIN_MODAL, $selector, $this->options); + } + + $this->registerEvents($selector, $this->events); + } + +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbNav.php b/www/protected/extensions/bootstrap/widgets/TbNav.php new file mode 100644 index 0000000..a262d5b --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbNav.php @@ -0,0 +1,171 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap navigation menu widget. + * @see http://twitter.github.com/bootstrap/components.html#navbar + */ +class TbNav extends CWidget +{ + /** + * @var string the menu type. + */ + public $type; + /** + * @var boolean whether the menu items should be stacked on top of each other. + */ + public $stacked = false; + /** + * @var string|array the scrollspy target or configuration. + */ + public $scrollspy; + /** + * @var array list of menu items. Each menu item is specified as an array of name-value pairs. + */ + public $items = array(); + /** + * @var boolean whether the labels for menu items should be HTML-encoded. Defaults to true. + */ + public $encodeLabel = true; + /** + * @var boolean whether to automatically activate items according to whether their route setting + * matches the currently requested route. Defaults to true. + */ + public $activateItems = true; + /** + * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active. + */ + public $activateParents = false; + /** + * @var boolean whether to hide empty menu items. + */ + public $hideEmptyItems = true; + /** + * @var array HTML attributes for the menu's root container tag. + */ + public $htmlOptions = array(); + + // todo: consider supporting these. + //public $submenuHtmlOptions = array(); + //public $linkLabelWrapper; + //public $linkLabelWrapperHtmlOptions=array(); + //public $itemCssClass; + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + $route = $this->controller->getRoute(); + if ($this->stacked) { + TbHtml::addCssClass('nav-stacked', $this->htmlOptions); + } + if (isset($this->scrollspy)) { + if (is_string($this->scrollspy)) { + $this->scrollspy = array('target' => $this->scrollspy); + } + $this->widget('bootstrap.widgets.TbScrollspy', $this->scrollspy); + } + $this->items = $this->normalizeItems($this->items, $route, $hasActiveChild); + } + + /** + * Runs the widget. + */ + public function run() + { + if (!empty($this->items)) { + echo TbHtml::nav($this->type, $this->items, $this->htmlOptions); + } + } + + /** + * Normalizes the menu items. + * @param array $items the items to be normalized. + * @param string $route the route of the current request. + * @param boolean $active whether there is an active child menu item. + * @return array the normalized menu items. + */ + protected function normalizeItems($items, $route, &$active) + { + foreach ($items as $i => $item) { + // skip dividers + if (is_string($item)) { + continue; + } + + if (isset($item['visible']) && !$item['visible']) { + unset($items[$i]); + continue; + } + + TbArray::defaultValue('label', '', $item); + + if ($this->encodeLabel) { + $items[$i]['label'] = CHtml::encode($item['label']); + } + + $hasActiveChild = false; + + if (isset($item['items']) && !empty($item['items'])) { + $items[$i]['items'] = $this->normalizeItems($item['items'], $route, $hasActiveChild); + + if (empty($items[$i]['items']) && $this->hideEmptyItems) { + unset($items[$i]['items']); + if (!isset($item['url'])) { + unset($items[$i]); + continue; + } + } + } + + if (!isset($item['active'])) { + if ($this->activateParents && $hasActiveChild || $this->activateItems && $this->isItemActive( + $item, + $route + ) + ) { + $active = $items[$i]['active'] = true; + } else { + $items[$i]['active'] = false; + } + } else { + if ($item['active']) { + $active = true; + } + } + } + + return array_values($items); + } + + /** + * Checks whether a menu item is active. + * @param array $item the menu item to be checked. + * @param string $route the route of the current request. + * @return boolean whether the menu item is active. + */ + protected function isItemActive($item, $route) + { + if (isset($item['url']) && is_array($item['url']) && !strcasecmp(trim($item['url'][0], '/'), $route)) { + unset($item['url']['#']); + if (count($item['url']) > 1) { + foreach (array_splice($item['url'], 1) as $name => $value) { + if (!isset($_GET[$name]) || $_GET[$name] != $value) { + return false; + } + } + } + return true; + } + return false; + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbNavbar.php b/www/protected/extensions/bootstrap/widgets/TbNavbar.php new file mode 100644 index 0000000..ea5f9d6 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbNavbar.php @@ -0,0 +1,129 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap navbar widget. + * @see http://twitter.github.com/bootstrap/components.html#navbar + */ +class TbNavbar extends CWidget +{ + /** + * @var string the navbar color. + */ + public $color; + /** + * @var string the brand label text. + */ + public $brandLabel; + /** + * @var mixed the brand url. + */ + public $brandUrl; + /** + * @var array the HTML attributes for the brand link. + */ + public $brandOptions = array(); + /** + * @var string nanvbar display type. + */ + public $display = TbHtml::NAVBAR_DISPLAY_FIXEDTOP; + /** + * @var boolean whether the navbar spans over the whole page. + */ + public $fluid = false; + /** + * @var boolean whether to enable collapsing of the navbar on narrow screens. + */ + public $collapse = false; + /** + * @var array additional HTML attributes for the collapse widget. + */ + public $collapseOptions = array(); + /** + * @var array list of navbar item. + */ + public $items = array(); + /** + * @var array the HTML attributes for the navbar. + */ + public $htmlOptions = array(); + + /** + * Initializes the widget. + */ + public function init() + { + if ($this->brandLabel !== false) { + if (!isset($this->brandLabel)) { + $this->brandLabel = CHtml::encode(Yii::app()->name); + } + + if (!isset($this->brandUrl)) { + $this->brandUrl = Yii::app()->homeUrl; + } + } + if (isset($this->color)) { + TbArray::defaultValue('color', $this->color, $this->htmlOptions); + } + if (isset($this->display) && $this->display !== TbHtml::NAVBAR_DISPLAY_NONE) { + TbArray::defaultValue('display', $this->display, $this->htmlOptions); + } + } + + /** + * Runs the widget. + */ + public function run() + { + $brand = $this->brandLabel !== false + ? TbHtml::navbarBrandLink($this->brandLabel, $this->brandUrl, $this->brandOptions) + : ''; + ob_start(); + foreach ($this->items as $item) { + if (is_string($item)) { + echo $item; + } else { + $widgetClassName = TbArray::popValue('class', $item); + if ($widgetClassName !== null) { + $this->controller->widget($widgetClassName, $item); + } + } + } + $items = ob_get_clean(); + ob_start(); + if ($this->collapse !== false) { + TbHtml::addCssClass('nav-collapse', $this->collapseOptions); + ob_start(); + /* @var TbCollapse $collapseWidget */ + $collapseWidget = $this->controller->widget( + 'bootstrap.widgets.TbCollapse', + array( + 'toggle' => false, // navbars are collapsed by default + 'content' => $items, + 'htmlOptions' => $this->collapseOptions, + ) + ); + $collapseContent = ob_get_clean(); + echo TbHtml::navbarCollapseLink('#' . $collapseWidget->getId()); + echo $brand . $collapseContent; + + } else { + echo $brand . $items; + } + $containerContent = ob_get_clean(); + $containerOptions = TbArray::popValue('containerOptions', $this->htmlOptions, array()); + TbHtml::addCssClass($this->fluid ? 'container-fluid' : 'container', $containerOptions); + ob_start(); + echo TbHtml::openTag('div', $containerOptions); + echo $containerContent; + echo ''; + $content = ob_get_clean(); + echo TbHtml::navbar($content, $this->htmlOptions); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbPager.php b/www/protected/extensions/bootstrap/widgets/TbPager.php new file mode 100644 index 0000000..2145b68 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbPager.php @@ -0,0 +1,158 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap pager widget. + * http://twitter.github.com/bootstrap/components.html#pagination + */ +class TbPager extends CBasePager +{ + /** + * @var string the pager size. + */ + public $size; + /** + * @var integer maximum number of page buttons that can be displayed. + */ + public $maxButtonCount = 5; + /** + * @var string the text label for the next page button. + */ + public $nextPageLabel = '›'; + /** + * @var string the text label for the previous page button. + */ + public $prevPageLabel = '‹'; + /** + * @var string the text label for the first page button. + */ + public $firstPageLabel = '«'; + /** + * @var string the text label for the last page button. + */ + public $lastPageLabel = '»'; + + /** + * @var boolean whether the "first" and "last" buttons should be hidden. + * Defaults to false. + */ + public $hideFirstAndLast = false; + /** + * @var array HTML attributes for the pager container tag. + */ + public $htmlOptions = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + if (isset($this->size)) { + TbArray::defaultValue('size', $this->size, $this->htmlOptions); + } + } + + /** + * Runs the widget. + */ + public function run() + { + $links = $this->createPageLinks(); + if (!empty($links)) { + echo TbHtml::pagination($links, $this->htmlOptions); + } + } + + /** + * Creates the page buttons. + * @return array a list of page buttons (in HTML code). + */ + protected function createPageLinks() + { + if (($pageCount = $this->getPageCount()) <= 1) { + return array(); + } + + list($beginPage, $endPage) = $this->getPageRange(); + + $currentPage = $this->getCurrentPage(false); // currentPage is calculated in getPageRange() + $links = array(); + + // first page + if (!$this->hideFirstAndLast) { + $links[] = $this->createPageLink($this->firstPageLabel, 0, $currentPage <= 0, false); + } + + // prev page + if (($page = $currentPage - 1) < 0) { + $page = 0; + } + + $links[] = $this->createPageLink($this->prevPageLabel, $page, $currentPage <= 0, false); + + // internal pages + for ($i = $beginPage; $i <= $endPage; ++$i) { + $links[] = $this->createPageLink($i + 1, $i, false, $i == $currentPage); + } + + // next page + if (($page = $currentPage + 1) >= $pageCount - 1) { + $page = $pageCount - 1; + } + + $links[] = $this->createPageLink($this->nextPageLabel, $page, $currentPage >= $pageCount - 1, false); + + // last page + if (!$this->hideFirstAndLast) { + $links[] = $this->createPageLink( + $this->lastPageLabel, + $pageCount - 1, + $currentPage >= $pageCount - 1, + false + ); + } + + return $links; + } + + /** + * Creates a page link. + * @param string $label the link label text. + * @param integer $page the page number. + * @param boolean $visible whether the link is disabled. + * @param boolean $active whether the link is active. + * @return string the generated link. + */ + protected function createPageLink($label, $page, $disabled, $active) + { + return array( + 'label' => $label, + 'url' => $this->createPageUrl($page), + 'disabled' => $disabled, + 'active' => $active, + ); + } + + /** + * @return array the begin and end pages that need to be displayed. + */ + protected function getPageRange() + { + $currentPage = $this->getCurrentPage(); + $pageCount = $this->getPageCount(); + $beginPage = max(0, $currentPage - (int)($this->maxButtonCount / 2)); + if (($endPage = $beginPage + $this->maxButtonCount - 1) >= $pageCount) { + $endPage = $pageCount - 1; + $beginPage = max(0, $endPage - $this->maxButtonCount + 1); + } + return array($beginPage, $endPage); + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbScrollspy.php b/www/protected/extensions/bootstrap/widgets/TbScrollspy.php new file mode 100644 index 0000000..bef810b --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbScrollspy.php @@ -0,0 +1,57 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap scrollspy widget. + * @see http://twitter.github.com/bootstrap/javascript.html#scrollspy + */ +class TbScrollspy extends CWidget +{ + /** + * @var string the CSS selector for the scrollspy element. + */ + public $selector = 'body'; + /** + * @var string the CSS selector for the spying element. + */ + public $target; + /** + * @var integer the scroll offset (in pixels). + */ + public $offset; + /** + * @var string[] $events the JavaScript event configuration (name=>handler). + */ + public $events = array(); + + /** + * Initializes the widget. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + } + + /** + * Runs the widget. + */ + public function run() + { + // todo: think of a better way of doing this. + $script = "jQuery('{$this->selector}').attr('data-spy', 'scroll');"; + if (isset($this->target)) { + $script .= "jQuery('{$this->selector}').attr('data-target', '{$this->target}');"; + } + if (isset($this->offset)) { + $script .= "jQuery('{$this->selector}').attr('data-offset', '{$this->offset}');"; + } + Yii::app()->clientScript->registerScript($this->getId(), $script, CClientScript::POS_BEGIN); + $this->registerEvents($this->selector, $this->events); + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbTabs.php b/www/protected/extensions/bootstrap/widgets/TbTabs.php new file mode 100644 index 0000000..4722407 --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbTabs.php @@ -0,0 +1,125 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap tabs widget. + */ +class TbTabs extends CWidget +{ + /** + * @var string the type of tabs to display. Valid values are 'tabs' and 'pills' (defaults to 'tabs'). + * @see TbHtml::$navStyles + */ + public $type = TbHtml::NAV_TYPE_TABS; + /** + * @var string the placement of the tabs. Valid values are 'right, 'left' and 'below'. + * @see TbHtml::tabPlacements + */ + public $placement; + /** + * @var array the tab configuration. + */ + public $tabs = array(); + /** + * @var array additional data submitted to the views. + */ + public $viewData; + /** + * @var string a javascript function that This event fires on tab show, but before the new tab has been shown. + * Use `event.target` and `event.relatedTarget` to target the active tab and the previous active tab (if available) + * respectively. + */ + public $onShow; + /** + * @var string a javascript function that fires on tab show after a tab has been shown. Use `event.target` and + * `event.relatedTarget` to target the active tab and the previous active tab (if available) respectively. + */ + public $onShown; + /** + * @var array the HTML attributes for the widget container. + */ + public $htmlOptions = array(); + /** + * @var string[] the Javascript event handlers. + */ + protected $events = array(); + + /** + * Widget's initialization method + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->copyId(); + TbArray::defaultValue('placement', $this->placement, $this->htmlOptions); + $this->initEvents(); + } + + /** + * Initialize events if any + */ + public function initEvents() + { + foreach (array('onShow', 'onShown') as $event) { + if ($this->$event !== null) { + $modalEvent = strtolower(substr($event, 2)); + if ($this->$event instanceof CJavaScriptExpression) { + $this->events[$modalEvent] = $this->$event; + } else { + $this->events[$modalEvent] = new CJavaScriptExpression($this->$event); + } + } + } + } + + /** + * Widget's run method + */ + public function run() + { + $this->tabs = $this->normalizeTabs($this->tabs); + echo TbHtml::tabbable($this->type, $this->tabs, $this->htmlOptions); + $this->registerClientScript(); + } + + /** + * Normalizes the tab configuration. + * @param array $tabs a reference to the tabs tab configuration. + */ + protected function normalizeTabs($tabs) + { + $controller = $this->getController(); + if (isset($controller)) { + foreach ($tabs as &$tabOptions) { + $items = TbArray::getValue('items', $tabOptions, array()); + if (!empty($items)) { + $tabOptions['items'] = $this->normalizeTabs($items); + } else { + if (isset($tabOptions['view'])) { + $view = TbArray::popValue('view', $tabOptions); + if ($controller->getViewFile($view) !== false) { + $tabOptions['content'] = $controller->renderPartial($view, $this->viewData, true); + } + } + } + } + } + return $tabs; + } + + /** + * Registers necessary client scripts. + */ + public function registerClientScript() + { + $selector = '#' . $this->htmlOptions['id']; + Yii::app()->clientScript->registerScript(__CLASS__ . $selector, "jQuery('{$selector}').tab('show');"); + $this->registerEvents($selector, $this->events); + } +} \ No newline at end of file diff --git a/www/protected/extensions/bootstrap/widgets/TbThumbnails.php b/www/protected/extensions/bootstrap/widgets/TbThumbnails.php new file mode 100644 index 0000000..0b35fba --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbThumbnails.php @@ -0,0 +1,70 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap thumbnails widget. + * http://twitter.github.com/bootstrap/components.html#thumbnails + */ +class TbThumbnails extends TbListView +{ + /** + * @var mixed a PHP expression that is evaluated for every item and whose result is used + * as the URL for the thumbnail. + */ + public $url; + /** + * @var integer the number of grid columns that the thumbnails spans over. + */ + public $span; + + /** + * Initializes the widget + */ + public function init() + { + parent::init(); + + if (isset($this->itemsCssClass)) { + TbHtml::addCssClass($this->itemsCssClass, $this->htmlOptions); + } + } + + /** + * Renders the data items for the view. + * Each item is corresponding to a single data model instance. + */ + public function renderItems() + { + $thumbnails = array(); + $data = $this->dataProvider->getData(); + + if (!empty($data)) { + $owner = $this->getOwner(); + $render = $owner instanceof CController ? 'renderPartial' : 'render'; + foreach ($data as $i => $row) { + $thumbnail = array(); + $d = $this->viewData; + $d['index'] = $i; + $d['data'] = $row; + $d['widget'] = $this; + $thumbnail['caption'] = $owner->$render($this->itemView, $d, true); + if (isset($this->url)) { + $thumbnail['url'] = $this->evaluateExpression($this->url, array('data' => $row)); + } + if (isset($this->span)) { + $thumbnail['span'] = $this->span; + } + $thumbnails[] = $thumbnail; + } + echo TbHtml::thumbnails($thumbnails, $this->htmlOptions); + } else { + $this->renderEmptyText(); + } + } +} diff --git a/www/protected/extensions/bootstrap/widgets/TbTypeAhead.php b/www/protected/extensions/bootstrap/widgets/TbTypeAhead.php new file mode 100644 index 0000000..2e3751a --- /dev/null +++ b/www/protected/extensions/bootstrap/widgets/TbTypeAhead.php @@ -0,0 +1,134 @@ + + * @copyright Copyright © Christoffer Niska 2013- + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @package bootstrap.widgets + */ + +/** + * Bootstrap typeahead widget. + */ +class TbTypeAhead extends CInputWidget +{ + /** + * @var mixed the data source to query against. May be an array of strings or a function. The function is passed + * two arguments, the query value in the input field and the process callback. The function may be used synchronously + * by returning the data source directly or asynchronously via the process callback's single argument. + */ + public $source = array(); + + /** + * @var int the max number of items to display in the dropdown. Defaults to 8. + */ + public $items = 8; + + /** + * @var int the minimum character length needed before triggering autocomplete suggestions + */ + public $minLength = 1; + + /** + * @var string javascript function the method used to determine if a query matches an item. Accepts a single argument, the item + * against which to test the query. Access the current query with this.query. Return a boolean true if query is a + * match. Case insensitive. + */ + public $matcher; + + /** + * @var string javascript function method used to sort autocomplete results. Accepts a single argument items and has + * the scope of the typeahead instance. Reference the current query with this.query. Exact match, case sensitive, + * case insensitive + */ + public $sorter; + + /** + * @var string javascript the method used to return selected item. Accepts a single argument, the item and has the + * scope of the typeahead instance. Returns selected item. + */ + public $updater; + + /** + * @var string javascript method used to highlight autocomplete results. Accepts a single argument item and has the + * scope of the typeahead instance. Should return html. Highlights all default matches + */ + public $highlighter; + + /** + * @var array the plugin options + */ + protected $pluginOptions = array(); + + /** + * Widget's initialization method. + */ + public function init() + { + $this->attachBehavior('TbWidget', new TbWidget); + $this->initOptions(); + } + + /** + * Initializes the plugin options + */ + public function initOptions() + { + $options = array(); + foreach (array('matcher', 'sorter', 'updater', 'highlighter') as $fn) { + if ($this->$fn !== null) { + if ($this->$fn instanceof CJavaScriptExpression) { + $options[$fn] = $this->$fn; + } else { + $options[$fn] = new CJavaScriptExpression($this->$fn); + } + } + } + + $this->pluginOptions = TbArray::merge( + array( + 'source' => $this->source, + 'items' => $this->items, + 'minLength' => $this->minLength + ), + $options + ); + } + + /** + * Widget's run method. + */ + public function run() + { + $this->renderField(); + $this->registerClientScript(); + } + + /** + * Renders field + */ + public function renderField() + { + list($name, $id) = $this->resolveNameID(); + + TbArray::defaultValue('id', $id, $this->htmlOptions); + TbArray::defaultValue('name', $name, $this->htmlOptions); + + // by using TbHtml we support all bootstrap options + if ($this->hasModel()) { + echo TbHtml::activeTextField($this->model, $this->attribute, $this->htmlOptions); + } else { + echo TbHtml::textField($name, $this->value, $this->htmlOptions); + } + } + + /** + * Register required scripts. + */ + public function registerClientScript() + { + /** @var TbApi $api */ + $selector = '#' . TbArray::getValue('id', $this->htmlOptions, $this->getId()); + $this->registerPlugin(TbApi::PLUGIN_TYPEAHEAD, $selector, $this->pluginOptions); + } +} \ No newline at end of file diff --git a/www/protected/views/layouts/column1.php b/www/protected/views/layouts/column1_.php similarity index 100% rename from www/protected/views/layouts/column1.php rename to www/protected/views/layouts/column1_.php diff --git a/www/protected/views/layouts/column2.php b/www/protected/views/layouts/column2_.php similarity index 100% rename from www/protected/views/layouts/column2.php rename to www/protected/views/layouts/column2_.php diff --git a/www/protected/views/layouts/main.php b/www/protected/views/layouts/main.php index daf905e..56edd85 100644 --- a/www/protected/views/layouts/main.php +++ b/www/protected/views/layouts/main.php @@ -1,59 +1,101 @@ - - - + + + + + + - - - - - - - - - - + + + + + + bootstrap->register(); ?> + + + <?php echo CHtml::encode($this->pageTitle); ?> - + -
+ - + + +breadcrumbs)) + { + $this->widget('bootstrap.widgets.TbBreadcrumb', array( 'links'=>$this->breadcrumbs, - )); ?> - + )); + } +?> - + -
- - - -
+ + + + + + - + \ No newline at end of file