├── .gitignore ├── .jshintrc ├── .npmignore ├── API.md ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assert.js ├── docs ├── css │ ├── bootstrap.css │ ├── highlight.github.css │ └── style.css ├── demo │ ├── JSXTransformer.js │ ├── bundle.js │ ├── codemirror.css │ ├── index.html │ ├── index.jsx │ ├── react-0.12.2.js │ └── react-0.13.0-beta.1.js ├── index.html └── js │ └── highlight.js ├── gulpfile.js ├── index.js ├── package.json ├── src ├── .flowconfig └── assert.js ├── test ├── assert.js ├── browserify.js ├── fixtures │ ├── main.js │ └── main.json ├── index.js └── visitors.js ├── transform.js └── visitors.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | node_modules 3 | dev -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "maxerr" : 50, // {int} Maximum error before stopping 3 | 4 | // Enforcing 5 | "camelcase" : true, // true: Identifiers must be in camelCase 6 | "curly" : true, // true: Require {} for every new block or scope 7 | "eqeqeq" : true, // true: Require triple equals (===) for comparison 8 | "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() 9 | "immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` 10 | "indent" : 2, // {int} Number of spaces to use for indentation 11 | "latedef" : true, // true: Require variables/functions to be defined before being used 12 | "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()` 13 | "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` 14 | "noempty" : true, // true: Prohibit use of empty blocks 15 | "nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment) 16 | "quotmark" : false, // Quotation mark consistency: 17 | // false : do nothing (default) 18 | // true : ensure whatever is used is consistent 19 | // "single" : require single quotes 20 | // "double" : require double quotes 21 | "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) 22 | "unused" : true, // true: Require all defined variables be used 23 | "strict" : true, // true: Requires all functions run in ES5 Strict Mode 24 | 25 | // Environments 26 | "browser" : false, // Web Browser (window, document, etc) 27 | "node" : true // Node.js 28 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | *.log 3 | node_modules 4 | test 5 | docs 6 | dev 7 | src 8 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | ## Assert library 4 | 5 | A type is represented by an object with 2 properties: 6 | 7 | - name: string 8 | - validate: function 9 | 10 | The validate function has the following signature: 11 | 12 | ```js 13 | validate(x: any, ctx: ?Array, fast: ?boolean): ?Array 14 | ``` 15 | 16 | where 17 | 18 | ```js 19 | Failure = { 20 | actual: any; 21 | expected: Type; 22 | path: Array; 23 | } 24 | ``` 25 | 26 | `transform(source: string, options: ?object): string` 27 | 28 | Options: 29 | 30 | - `namespace`: string (default `f`) 31 | - `sourceMap`: boolean (default `false`) 32 | - `target`: string (one of ["es3"]) 33 | 34 | `f.define(name: string, is: (x: any) => boolean): Type` 35 | 36 | Defines a new basic type. 37 | 38 | `f.check(value: T, type: Type): T` 39 | 40 | - by default `instanceof` is used to check the type 41 | - if `type` owns a static `is(x: any)`, it will be used to check the type 42 | - if `value` is not of type `type`, `f.fail` will be called with a meaningful error message 43 | 44 | `f.list(type: Type, name: ?string): Type` 45 | 46 | Returns a type representing the list `Array`. 47 | 48 | `f.tuple(types: Array, name: ?string): Type` 49 | 50 | Returns a type representing the tuple `[...types]`. 51 | 52 | `f.shape(props: {[key:string]: Type}): Type` 53 | 54 | Returns a type representing the object `{p1: T1, p2: T2, ... p3: T3}`. 55 | 56 | `f.dict(domain: Type, codomain: Type, name: ?string): Type` 57 | 58 | Returns a type representing the dictionary type `{[key: domain]: codomain}`. 59 | 60 | `f.maybe(type: Type, name: ?string): Type` 61 | 62 | Returns a type representing the nullable type `?type`. 63 | 64 | `f.union(types: Array, name: ?string): Type` 65 | 66 | Returns a type representing the union `T1 | T2 | ... | Tn`. 67 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | > **Tags:** 4 | > - [New Feature] 5 | > - [Bug Fix] 6 | > - [Breaking Change] 7 | > - [Documentation] 8 | > - [Internal] 9 | > - [Polish] 10 | 11 | **Note**: Gaps between patch versions are faulty/broken releases. 12 | 13 | ## v0.2.7 14 | 15 | - **Bug Fix** 16 | + "type.is is not a function" when using constructor function with assert.union #21 (thanks @ivan) 17 | 18 | ## v0.2.6 19 | 20 | - **Bug Fix** 21 | + empty shapes are interpreted as dicts #20 22 | 23 | ## v0.2.5 24 | 25 | - **Internal** 26 | + Removed `debugger` statement #15 27 | 28 | ## v0.2.4 29 | 30 | - **Bug Fix** 31 | + Removed CRLF from `visitProgram` causing wrong bad sourceMaps 32 | - **Internal** 33 | + Upgrade to latest babelify 34 | 35 | ## v0.2.3 36 | 37 | - **Internal** 38 | + It shouldn't die if requiring JSON, fix #12 39 | 40 | ## v0.2.1 41 | 42 | - **Internal** 43 | + Changed the default namespace from `f` to `_f` to avoid likely name conflicts 44 | + Added a `visitProgram` to `visitor.js`. It adds `var _f = require("flowcheck/assert");` at the beginning of the file, fix #4 45 | + Added to `visitProgram` a `namespace.indexOf('require') === -1` check in order to not break flowcheck-loader (temporary) 46 | - **New Feature** 47 | + Added a boolean option `skipImport` (default `false`). If set to `true`, skips the `visitProgram` visitor (useful for tests or if you want to import by hand the module flowcheck/assert as a global) 48 | 49 | ## v0.2 50 | 51 | - **Polish** 52 | + Code refactoring 53 | - **Internal** 54 | + Added more tests 55 | 56 | ## v0.1 57 | 58 | - First release 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Giulio Canti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repo is deprecated, please migrate to [babel-plugin-tcomb](https://github.com/gcanti/babel-plugin-tcomb) which is now Flow compatible 2 | 3 | **Note**. If you are using babel you may want to take a look at [babel-plugin-tcomb](https://github.com/gcanti/babel-plugin-tcomb). 4 | 5 | # Why? 6 | 7 | Use types annotations today, even if you don't actually use Flow (or TypeScript). Then strip the assertions in production. 8 | 9 | Flowcheck comes with a built-in browserify transformer and supports sourcemaps for a seamless workflow integration. 10 | 11 | You can even use Flowcheck as a general purpose validation library. 12 | 13 | # How it works? 14 | 15 | Flowcheck adds asserts for each type annotation using jstransform. 16 | 17 | If an assert fails the debugger kicks in so you can inspect the stack and quickly find out what's wrong. 18 | 19 | # Demo live 20 | 21 | [https://gcanti.github.io/flowcheck](https://gcanti.github.io/flowcheck) 22 | 23 | # Workflow 24 | 25 | 1. Write your code adding type annotations 26 | 2. (optional) enable the Flow static type checker 27 | 3. enable Flowcheck.js and strip type annotations (with react-tools or 6to5) during development 28 | 4. disable Flowcheck.js in production for zero overhead 29 | 30 | # Differences with flow 31 | 32 | - Flowcheck tuples are fixed-length arrays [#227](https://github.com/facebook/flow/issues/227) 33 | - polymorphic types **are erased** 34 | - supports optional properties in objects (using `void` type) [#38](https://github.com/facebook/flow/issues/38) 35 | 36 | # Modules 37 | 38 | - a **source transformer** (transform.js) 39 | - a **browserify transformer** (index.js) 40 | - a **runtime assertion library** (assert.js) 41 | 42 | The transformer adds assertions for each type annotation. 43 | 44 | The assertion module checks the types at runtime. If an assert fails **the debugger kicks in** so you can inspect the stack and quickly find out what's wrong. 45 | 46 | # Plugins 47 | 48 | There is [flowcheck-loader](https://github.com/gaearon/flowcheck-loader) for Webpack which is equivalent to Flowcheck's Browserify transform. 49 | 50 | # Tests 51 | 52 | ```js 53 | npm test 54 | ``` 55 | 56 | # License 57 | 58 | MIT 59 | -------------------------------------------------------------------------------- /assert.js: -------------------------------------------------------------------------------- 1 | // flowcheck 0.2.7 2 | // https://github.com/gcanti/flowcheck 3 | // (c) 2015 Giulio Canti 4 | // flowcheck may be freely distributed under the MIT license. 5 | // (checked with Flow and transpiled with jsx) 6 | /* @flow */ 7 | 'use strict'; 8 | function getFunctionName(f) { 9 | return f.displayName || f.name || (""); 10 | } 11 | function Failure(actual, expected, ctx) { 12 | this.actual = actual; 13 | this.expected = expected; 14 | this.ctx = ctx; 15 | } 16 | Failure.prototype.toString = function () { 17 | var ctx = this.ctx ? this.ctx.join(' / ') : ''; 18 | ctx = ctx ? (", context: " + ctx) : ', (no context)'; 19 | return ("Expected an instance of " + this.expected.name + " got " + (Failure.stringify(this.actual) + ctx)); 20 | }; 21 | Failure.stringify = function (x) { 22 | try { // handle circular references 23 | return JSON.stringify(x, function (k, v) { 24 | if (typeof v === 'function') { 25 | return ("[" + getFunctionName(v) + ", Function]"); 26 | } // handle functions 27 | if (v instanceof RegExp) { 28 | return ("[" + String(v) + ", RegExp]"); 29 | } // handle regexps 30 | return v; 31 | }, 2); 32 | } catch (e) {} 33 | return String(x); 34 | }; 35 | function Type(name, validate) { 36 | this.name = name; 37 | this.validate = validate; 38 | } 39 | Type.prototype.is = function (x) { 40 | return this.validate(x, null, true) === null; 41 | }; 42 | function define(name, is) { 43 | var type = new Type(name, function (x, ctx) { 44 | return is(x) ? null : [new Failure(x, type, ctx)]; 45 | }); 46 | return type; 47 | } 48 | var Any = define('any', function () { 49 | return true; 50 | }); 51 | var Mixed = define('mixed', function () { 52 | return true; 53 | }); 54 | var Void = define('void', function (x) { 55 | return x === void 0; 56 | }); 57 | var Str = define('string', function (x) { 58 | return typeof x === 'string'; 59 | }); 60 | var Num = define('number', function (x) { 61 | return typeof x === 'number'; 62 | }); 63 | var Bool = define('boolean', function (x) { 64 | return x === true || x === false; 65 | }); 66 | var Arr = define('array', function (x) { 67 | return x instanceof Array; 68 | }); 69 | var Obj = define('object', function (x) { 70 | return x !== null && x !== undefined && typeof x === 'object' && !Arr.is(x); 71 | }); 72 | var Func = define('function', function (x) { 73 | return typeof x === 'function'; 74 | }); 75 | function validate(x, type, ctx, failOnFirstError) { 76 | if (type.validate) { 77 | return type.validate(x, ctx, failOnFirstError); 78 | } 79 | return x instanceof type ? null : [new Failure(x, type, ctx)]; 80 | } 81 | function list(type, name) { 82 | name = name || ("Array<" + type.name + ">"); 83 | return new Type(name, function (x, ctx, failOnFirstError) { 84 | ctx = ctx || []; 85 | ctx.push(name); 86 | // if x is not an array, fail fast 87 | if (!Arr.is(x)) { 88 | return [new Failure(x, Arr, ctx)]; 89 | } 90 | var errors = null, 91 | suberrors; 92 | for (var i = 0, len = x.length; i < len; i++) { 93 | suberrors = validate(x[i], type, ctx.concat(i)); 94 | if (suberrors) { 95 | if (failOnFirstError) { 96 | return suberrors; 97 | } 98 | errors = errors || []; 99 | errors.push.apply(errors, suberrors); 100 | } 101 | } 102 | return errors; 103 | }); 104 | } 105 | function optional(type, name) { 106 | name = name || (type.name + "?"); 107 | return new Type(name, function (x, ctx, failOnFirstError) { 108 | if (x === void 0) { 109 | return null; 110 | } 111 | ctx = ctx || []; 112 | ctx.push(name); 113 | return validate(x, type, ctx, failOnFirstError); 114 | }); 115 | } 116 | function maybe(type, name) { 117 | name = name || ("?" + type.name); 118 | return new Type(name, function (x, ctx, failOnFirstError) { 119 | if (x === null) { 120 | return null; 121 | } 122 | ctx = ctx || []; 123 | ctx.push(name); 124 | return validate(x, type, ctx, failOnFirstError); 125 | }); 126 | } 127 | function getName(type) { 128 | return type.name; 129 | } 130 | function tuple(types, name) { 131 | name = name || ("[" + types.map(getName).join(', ') + "]"); 132 | var dimension = types.length; 133 | var type = new Type(name, function (x, ctx, failOnFirstError) { 134 | ctx = ctx || []; 135 | // if x is not an array, fail fast 136 | if (!Arr.is(x)) { 137 | return [new Failure(x, Arr, ctx.concat(name))]; 138 | } 139 | // if x has a wrong length, fail failOnFirstError 140 | if (x.length !== dimension) { 141 | return [new Failure(x, type, ctx)]; 142 | } 143 | var errors = null, 144 | suberrors; 145 | for (var i = 0; i < dimension; i++) { 146 | suberrors = validate(x[i], types[i], ctx.concat(name, i)); 147 | if (suberrors) { 148 | if (failOnFirstError) { 149 | return suberrors; 150 | } 151 | errors = errors || []; 152 | errors.push.apply(errors, suberrors); 153 | } 154 | } 155 | return errors; 156 | }); 157 | return type; 158 | } 159 | function dict(domain, codomain, name) { 160 | name = name || ("{[key: " + domain.name + "]: " + codomain.name + "}"); 161 | return new Type(name, function (x, ctx, failOnFirstError) { 162 | ctx = ctx || []; 163 | // if x is not an object, fail fast 164 | if (!Obj.is(x)) { 165 | return [new Failure(x, Obj, ctx.concat(name))]; 166 | } 167 | var errors = null, 168 | suberrors; 169 | for (var k in x) { 170 | if (x.hasOwnProperty(k)) { 171 | // check domain 172 | suberrors = validate(k, domain, ctx.concat(name, k)); 173 | if (suberrors) { 174 | if (failOnFirstError) { 175 | return suberrors; 176 | } 177 | errors = errors || []; 178 | errors.push.apply(errors, suberrors); 179 | } 180 | // check codomain 181 | suberrors = validate(x[k], codomain, ctx.concat(name, k)); 182 | if (suberrors) { 183 | if (failOnFirstError) { 184 | return suberrors; 185 | } 186 | errors = errors || []; 187 | errors.push.apply(errors, suberrors); 188 | } 189 | } 190 | } 191 | return errors; 192 | }); 193 | } 194 | function shape(props, name) { 195 | name = name || ("{" + Object.keys(props).map(function (k) { 196 | return k + ': ' + props[k].name + ';'; 197 | }).join(' ') + "}"); 198 | return new Type(name, function (x, ctx, failOnFirstError) { 199 | ctx = ctx || []; 200 | // if x is not an object, fail fast 201 | if (!Obj.is(x)) { 202 | return [new Failure(x, Obj, ctx.concat(name))]; 203 | } 204 | var errors = null, 205 | suberrors; 206 | for (var k in props) { 207 | if (props.hasOwnProperty(k)) { 208 | suberrors = validate(x[k], props[k], ctx.concat(name, k)); 209 | if (suberrors) { 210 | if (failOnFirstError) { 211 | return suberrors; 212 | } 213 | errors = errors || []; 214 | errors.push.apply(errors, suberrors); 215 | } 216 | } 217 | } 218 | return errors; 219 | }); 220 | } 221 | function union(types, name) { 222 | name = name || types.map(getName).join(' | '); 223 | var type = new Type(name, function (x, ctx) { 224 | ctx = (ctx || []).concat(name); 225 | if (types.some(function (type) { 226 | return validate(x, type, ctx, true) === null; 227 | })) { 228 | return null; 229 | } 230 | return [new Failure(x, type, ctx)]; 231 | }); 232 | return type; 233 | } 234 | function slice(arr, start, end) { 235 | return Array.prototype.slice.call(arr, start, end); 236 | } 237 | function args(types, varargs) { 238 | var name = ("(" + types.map(getName).join(', ') + ", ..." + (varargs || Any).name + ")"); 239 | var length = types.length; 240 | var typesTuple = tuple(types); 241 | if (varargs) { 242 | varargs = list(varargs); 243 | } 244 | return new Type(name, function (x, ctx, failOnFirstError) { 245 | ctx = ctx || []; 246 | var args = x; 247 | // test if args is an array-like structure 248 | if (args.hasOwnProperty('length')) { 249 | args = slice(args, 0, length); 250 | // handle optional arguments filling the array with undefined values 251 | if (args.length < length) { 252 | args.length = length; 253 | } 254 | } 255 | var errors = null, 256 | suberrors; 257 | suberrors = typesTuple.validate(args, ctx.concat('arguments'), failOnFirstError); 258 | if (suberrors) { 259 | if (failOnFirstError) { 260 | return suberrors; 261 | } 262 | errors = errors || []; 263 | errors.push.apply(errors, suberrors); 264 | } 265 | if (varargs) { 266 | suberrors = varargs.validate(slice(x, length), ctx.concat('varargs'), failOnFirstError); 267 | if (suberrors) { 268 | if (failOnFirstError) { 269 | return suberrors; 270 | } 271 | errors = errors || []; 272 | errors.push.apply(errors, suberrors); 273 | } 274 | } 275 | return errors; 276 | }); 277 | } 278 | function check(x, type) { 279 | var errors = validate(x, type); 280 | if (errors) { 281 | var message = [].concat(errors).join('\n'); 282 | throw new TypeError(message); 283 | } 284 | return x; 285 | } 286 | module.exports = { 287 | Failure: Failure, 288 | Type: Type, 289 | define: define, 290 | any: Any, 291 | mixed: Mixed, 292 | 'void': Void, 293 | number: Num, 294 | string: Str, 295 | 'boolean': Bool, 296 | object: Obj, 297 | 'function': Func, 298 | list: list, 299 | optional: optional, 300 | maybe: maybe, 301 | tuple: tuple, 302 | dict: dict, 303 | shape: shape, 304 | union: union, 305 | arguments: args, 306 | check: check 307 | }; -------------------------------------------------------------------------------- /docs/css/bootstrap.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.1 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]: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}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.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>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} -------------------------------------------------------------------------------- /docs/css/highlight.github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | -webkit-text-size-adjust: none; 14 | } 15 | 16 | .hljs-comment, 17 | .diff .hljs-header, 18 | .hljs-javadoc { 19 | color: #999; 20 | font-style: italic; 21 | } 22 | 23 | .hljs-keyword, 24 | .css .rule .hljs-keyword, 25 | .hljs-winutils, 26 | .nginx .hljs-title, 27 | .hljs-subst, 28 | .hljs-request, 29 | .hljs-status { 30 | color: #A71D5D; 31 | } 32 | 33 | .hljs-number, 34 | .hljs-hexcolor, 35 | .ruby .hljs-constant { 36 | color: #a31515; 37 | } 38 | 39 | .hljs-string, 40 | .hljs-tag .hljs-value, 41 | .hljs-phpdoc, 42 | .hljs-dartdoc, 43 | .tex .hljs-formula { 44 | color: #DF5000; 45 | } 46 | 47 | .hljs-title, 48 | .hljs-id, 49 | .scss .hljs-preprocessor { 50 | color: #900; 51 | font-weight: bold; 52 | } 53 | 54 | .hljs-list .hljs-keyword, 55 | .hljs-subst { 56 | font-weight: normal; 57 | } 58 | 59 | .hljs-class .hljs-title, 60 | .hljs-type, 61 | .vhdl .hljs-literal, 62 | .tex .hljs-command { 63 | color: #458; 64 | font-weight: bold; 65 | } 66 | 67 | .hljs-tag, 68 | .hljs-tag .hljs-title, 69 | .hljs-rules .hljs-property, 70 | .django .hljs-tag .hljs-keyword { 71 | color: #000080; 72 | font-weight: normal; 73 | } 74 | 75 | .hljs-attribute, 76 | .hljs-variable, 77 | .lisp .hljs-body { 78 | color: #008080; 79 | } 80 | 81 | .hljs-regexp { 82 | color: #009926; 83 | } 84 | 85 | .hljs-symbol, 86 | .ruby .hljs-symbol .hljs-string, 87 | .lisp .hljs-keyword, 88 | .clojure .hljs-keyword, 89 | .scheme .hljs-keyword, 90 | .tex .hljs-special, 91 | .hljs-prompt { 92 | color: #990073; 93 | } 94 | 95 | .hljs-built_in { 96 | color: #0086b3; 97 | } 98 | 99 | .hljs-preprocessor, 100 | .hljs-pragma, 101 | .hljs-pi, 102 | .hljs-doctype, 103 | .hljs-shebang, 104 | .hljs-cdata { 105 | color: #999; 106 | font-weight: bold; 107 | } 108 | 109 | .hljs-deletion { 110 | background: #fdd; 111 | } 112 | 113 | .hljs-addition { 114 | background: #dfd; 115 | } 116 | 117 | .diff .hljs-change { 118 | background: #0086b3; 119 | } 120 | 121 | .hljs-chunk { 122 | color: #aaa; 123 | } 124 | -------------------------------------------------------------------------------- /docs/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #555; 3 | font-size: 16px; 4 | } 5 | header { 6 | border-bottom: 2px solid #ddd; 7 | margin-bottom: 2em; 8 | padding: 2em 0; 9 | color: #999; 10 | } 11 | footer { 12 | border-top: 2px solid #ddd; 13 | margin-top: 4em; 14 | padding: 2em 0; 15 | } 16 | code { 17 | background-color: #f0f0f0; 18 | color: #000; 19 | } 20 | pre { 21 | border: 1px solid #ccc; 22 | padding: 2em; 23 | background-color: transparent; 24 | margin: 2em 0; 25 | } 26 | pre code.hljs { 27 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 28 | padding: 0; 29 | background-color: transparent; 30 | } 31 | .alert-danger pre { 32 | border-color: #a94442; 33 | } 34 | p { 35 | margin: 1.5em 0; 36 | } 37 | a, a:hover { 38 | color: #CC2E39; 39 | } 40 | .preview { 41 | border: 1px solid #ccc; 42 | padding: 1em; 43 | margin: 2em 0; 44 | -webkit-box-shadow: 0px 1px 4px 0px rgba(0,0,0,0.2); 45 | -moz-box-shadow: 0px 1px 4px 0px rgba(0,0,0,0.2); 46 | box-shadow: 0px 1px 4px 0px rgba(0,0,0,0.2); 47 | } 48 | pre.value { 49 | font-family: Menlo,Monaco,Consolas,"Courier New",monospace; 50 | background-color: #dff0d8; 51 | display: none; 52 | } 53 | -------------------------------------------------------------------------------- /docs/demo/codemirror.css: -------------------------------------------------------------------------------- 1 | .CodeMirror{font-family:monospace;height:300px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror div.CodeMirror-cursor{border-left:1px solid #000}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-moz-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}.cm-tab{display:inline-block}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-invalidchar,.cm-s-default .cm-error{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{line-height:1;position:relative;overflow:hidden;background:#fff;color:#000}.CodeMirror-scroll{margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-sizer{position:relative;border-right:30px solid transparent;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;padding-bottom:30px;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;-moz-box-sizing:content-box;box-sizing:content-box;padding-bottom:30px;margin-bottom:-32px;display:inline-block}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;border-right:none;width:0}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:1}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}} -------------------------------------------------------------------------------- /docs/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Flowcheck.js compiler 8 | 9 | 10 | 11 | 12 | 21 | 22 | 23 |
24 |
25 |
26 |
27 | Flowcheck 28 |
29 |
30 | Open source (MIT). Made by Giulio Canti 31 |
32 |
33 |
34 |
35 |
36 |

Flowcheck compiler

37 |
38 |
39 |
40 |
41 | 42 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /docs/demo/index.jsx: -------------------------------------------------------------------------------- 1 | // watchify -t reactify docs/demo/index.jsx -o docs/demo/bundle.js -v -x react 2 | 3 | 'use strict'; 4 | 5 | var React = require('react'); 6 | var CodeMirror = require('react-code-mirror'); 7 | require('codemirror/mode/javascript/javascript'); 8 | var transform = require('../../transform').transform; 9 | var beautify = require('js-beautify'); 10 | //var to5 = require('6to5-core').transform; 11 | 12 | window._f = require('../../assert'); 13 | window.React = React; 14 | 15 | var defaultValue = document.getElementById('example').innerText; 16 | 17 | var App = React.createClass({ 18 | 19 | getInitialState: function () { 20 | return { 21 | value: defaultValue, 22 | assertions: true, 23 | harmony: false, 24 | stripTypes: false, 25 | beautify: true, 26 | error: null 27 | }; 28 | }, 29 | 30 | compile: function (value, options) { 31 | options = options || this.state; 32 | var code = value; 33 | try { 34 | // flowcheck 35 | if (options.assertions) { 36 | code = transform(code, { 37 | skipImport: options.skipImport 38 | }); 39 | } 40 | // harmony 41 | /* 42 | code = to5(code, { 43 | stripTypes: options.stripTypes 44 | }).code; 45 | */ 46 | code = JSXTransformer.transform(code, { 47 | harmony: options.harmony, 48 | stripTypes: options.stripTypes 49 | }).code; 50 | // beautify 51 | if (options.beautify) { 52 | code = beautify(code, { 53 | indent_size: 2 54 | }); 55 | } 56 | } catch (e) { 57 | code = e.message; 58 | } 59 | return code; 60 | }, 61 | 62 | onSourceChange: function (evt) { 63 | this.setState({ 64 | value: evt.target.value, 65 | error: null 66 | }); 67 | }, 68 | 69 | onAssertionsChange: function (evt) { 70 | this.setState({assertions: evt.target.checked}); 71 | }, 72 | 73 | onHarmonyChange: function (evt) { 74 | this.setState({harmony: evt.target.checked}); 75 | }, 76 | 77 | onStripTypesChange: function (evt) { 78 | this.setState({stripTypes: evt.target.checked}); 79 | }, 80 | 81 | onBeautifyChange: function (evt) { 82 | this.setState({beautify: evt.target.checked}); 83 | }, 84 | 85 | run: function () { 86 | try { 87 | var code = this.compile(this.state.value, { 88 | assertions: true, 89 | harmony: true, 90 | stripTypes: true, 91 | skipImport: true 92 | }); 93 | eval(code); 94 | } catch (e) { 95 | console.error(e.message); 96 | this.setState({error: e.message}); 97 | } 98 | }, 99 | 100 | render: function () { 101 | var code = this.compile(this.state.value); 102 | var alert = this.state.error ? ( 103 |
104 | {this.state.error} 105 |
106 | ) : null; 107 | return ( 108 |
109 |
110 |

Source (live code editor)

111 |
112 | 119 |
120 |

React preview

121 |

use React.render(..., preview);

122 |
123 |
124 |
125 |

Output

126 |
127 | 135 |
136 |
137 | 140 | 143 | 146 | 149 |
150 |
151 | 152 |

Output to the console, when an assert fails the debugger kicks in

153 |
154 |
155 | {alert} 156 |
157 |
158 |
159 | ); 160 | } 161 | 162 | }); 163 | 164 | React.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Flowcheck.js 8 | 9 | 10 | 16 | 17 | 18 | 19 | 53 | 54 | 55 |
56 |
57 |

Flowcheck.js

58 |

Runtime type checking for Flow.

59 |

"Si vis pacem, para bellum"
(Vegetius 5th century)

60 |
61 |
62 |
63 |
64 |
65 |
66 | Twitter 67 |
68 |
69 | Blog 70 |
71 |
72 | Github 73 |
74 |
75 | Demo 76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |

Why?

84 |

Use types annotations today, even if you don't actually use Flow (or TypeScript). Then strip the assertions in production.

85 |

Flowcheck comes with a built-in browserify transformer and supports sourcemaps for a seamless workflow integration.

86 |

You can even use Flowcheck as a general purpose validation library.

87 |
88 |
89 |

How it works?

90 |

Flowcheck adds asserts for each type annotation using jstransform.

91 |

If an assert fails the debugger kicks in so you can inspect the stack and quickly find out what's wrong.

92 |
93 |
94 |

Workflow

95 |
    96 |
  1. Write your code adding type annotations
  2. 97 |
  3. (optional) enable the Flow static type checker
  4. 98 |
  5. enable Flowcheck.js and strip type annotations (with react-tools or 6to5) during development
  6. 99 |
  7. disable Flowcheck.js in production for zero overhead
  8. 100 |
101 |
102 |
103 |
104 |
105 |

Example

106 |
107 |
108 |
109 |
110 |

Input

111 |

112 | // basic types
113 | var n: number = 1;
114 | 
115 | // lists
116 | var arr: Array<string> = ['a', 'b'];
117 | 
118 | // functions
119 | function sum(a: number, b: number) {
120 |   return a + b;
121 | }
122 | 
123 | // type alias
124 | type MyType = Array<number>;
125 | 
126 | // ES6 classes
127 | class Person {
128 |   constructor(name: string, age: number) {
129 |     this.name = name;
130 |     this.age = age;
131 |   }
132 | }
133 | 
134 |
135 |
136 |

Output

137 |

138 | var _f = require("flowcheck/assert");
139 | 
140 | // basic types
141 | var n = _f.check(1, _f.number);
142 | 
143 | // lists
144 | var arr = _f.check(['a', 'b'], _f.list(_f.string));
145 | 
146 | // functions
147 | function sum(a, b) {
148 |   f.check(arguments, _f.args([_f.number, _f.number]));
149 |   return a + b;
150 | }
151 | 
152 | // type alias
153 | var MyType = _f.list(_f.number);
154 | 
155 | // ES6 classes
156 | class Person {
157 |   constructor(name, age) {
158 |     _f.check(arguments, _f.args([_f.string, _f.number]));
159 |     this.name = name;
160 |     this.age = age;
161 |   }
162 | }
163 | 
164 |
165 |
166 |
167 |
168 |

Quick setup

169 |

170 | npm install flowcheck
171 | browserify -t flowcheck -t [reactify --strip-types] input.js -o output.js
172 | 
173 |
174 |
175 |
176 |
177 | 178 |
179 |
180 |
181 | 184 |
185 |
186 |
187 |
188 |
189 |
190 | Twitter - 191 | Blog - 192 | Github - 193 | Demo 194 |
195 |
196 | Open source (MIT). Made by Giulio Canti 197 |
198 |
199 |
200 |
201 | 202 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /docs/js/highlight.js: -------------------------------------------------------------------------------- 1 | !function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,"")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:"start",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"==e.event?i:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else"start"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");c[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\b[A-Za-z0-9_]+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t";return o+=e+'">',o+n+i}function d(){if(!w.k)return n(y);var e="",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),"continuous"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(M+=r,y=""):e.eB?(M+=n(t)+r,y=""):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=""),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y="",a.starts&&b(a.starts,""),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme "'+t+'" for mode "'+(w.cN||"")+'"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: "'+e+'"');u(x);for(var w=o||x,L={},M="",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var y="",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+="");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf("Illegal"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),r&&a.push(r),a.join(" ").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",h,!1),addEventListener("load",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("javascript",function(r){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",r:10,v:[{b:/^\s*('|")use strict('|")/},{b:/^\s*('|")use asm('|")/}]},r.ASM,r.QSM,r.CLCM,r.CBCM,r.CNM,{b:"("+r.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[r.CLCM,r.CBCM,r.RM,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[r.inherit(r.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[r.CLCM,r.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+r.IR,r:0}]}}); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var gulp = require('gulp'); 4 | var header = require('gulp-header'); 5 | var jshint = require('gulp-jshint'); 6 | var react = require('gulp-react'); 7 | var beautify = require('gulp-beautify'); 8 | var stylish = require('jshint-stylish'); 9 | var pkg = require('./package.json'); 10 | 11 | var banner = [ 12 | '// <%= pkg.name %> <%= pkg.version %>', 13 | '// <%= pkg.homepage %>', 14 | '// (c) 2015 <%= pkg.author %>', 15 | '// <%= pkg.name %> may be freely distributed under the MIT license.', 16 | '// (checked with Flow and transpiled with jsx)', 17 | '' 18 | ].join('\n'); 19 | 20 | var src = './src/**/*.js*'; 21 | 22 | gulp.task('transpile', function() { 23 | return gulp.src(src) 24 | .pipe(react({ 25 | harmony: true, 26 | stripTypes: true 27 | })) 28 | .pipe(header(banner, {pkg: pkg})) 29 | .pipe(beautify({ 30 | indentSize: 2, 31 | preserveNewlines: false 32 | })) 33 | .pipe(gulp.dest('.')); 34 | }); 35 | 36 | gulp.task('lint', ['transpile'], function() { 37 | return gulp.src(['./assert.js', './transform.js', './visitors.js', './test/*.js']) 38 | .pipe(jshint()) 39 | .pipe(jshint.reporter(stylish)); 40 | }); 41 | 42 | gulp.task('default', ['lint']); 43 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var transform = require('./transform').transform; 4 | var through = require('through'); 5 | 6 | module.exports = function (file, options) { 7 | 8 | if (/\.json$/.test(file)) { 9 | return through(); 10 | } 11 | 12 | var data = ''; 13 | function write(chunk) { 14 | return data += chunk; 15 | } 16 | 17 | function compile() { 18 | try { 19 | var transformed = transform(data, options); 20 | this.queue(transformed); 21 | } catch (error) { 22 | error.name = 'FlowcheckError'; 23 | error.message = file + ': ' + error.message; 24 | error.fileName = file; 25 | this.emit('error', error); 26 | } 27 | return this.queue(null); 28 | } 29 | 30 | return through(write, compile); 31 | }; 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flowcheck", 3 | "version": "0.2.7", 4 | "description": "Runtime type checking for Flow", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test | tap-spec" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/gcanti/flowcheck.git" 12 | }, 13 | "author": "Giulio Canti ", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/gcanti/flowcheck/issues" 17 | }, 18 | "homepage": "https://github.com/gcanti/flowcheck", 19 | "dependencies": { 20 | "jstransform": "^8.2.0", 21 | "through": "^2.3.6" 22 | }, 23 | "devDependencies": { 24 | "babelify": "^6.0.2", 25 | "browserify": "^8.1.1", 26 | "gulp": "^3.8.11", 27 | "gulp-beautify": "^1.1.2", 28 | "gulp-header": "^1.2.2", 29 | "gulp-jshint": "^1.9.2", 30 | "gulp-react": "^2.0.0", 31 | "js-beautify": "^1.5.4", 32 | "jshint-stylish": "^1.0.0", 33 | "react-code-mirror": "^3.0.3", 34 | "reactify": "^1.1.0", 35 | "tap-spec": "^2.1.1", 36 | "tape": "^3.0.3" 37 | }, 38 | "keywords": [ 39 | "Flow", 40 | "Flowtype", 41 | "TypeScript", 42 | "AtScript", 43 | "runtime", 44 | "checking" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /src/.flowconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcanti/flowcheck/7c29f7ebdd962b4cc3b26771a1b3c1319b5137c5/src/.flowconfig -------------------------------------------------------------------------------- /src/assert.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | 'use strict'; 4 | 5 | type ValidationContext = Array; 6 | type ValidationFunction = (x: any, ctx?: ?ValidationContext, failOnFirstError?: boolean) => ?Array; 7 | type Predicate = (x: any) => boolean; 8 | 9 | function getFunctionName (f: any): string { 10 | return f.displayName || f.name || ``; 11 | } 12 | 13 | class Failure { 14 | 15 | actual: any; 16 | expected: Type; 17 | ctx: ?ValidationContext; 18 | 19 | constructor(actual: any, expected: Type, ctx?: ?ValidationContext) { 20 | this.actual = actual; 21 | this.expected = expected; 22 | this.ctx = ctx; 23 | } 24 | 25 | toString(): string { 26 | var ctx = this.ctx ? this.ctx.join(' / ') : ''; 27 | ctx = ctx ? `, context: ${ctx}` : ', (no context)'; 28 | return `Expected an instance of ${this.expected.name} got ${Failure.stringify(this.actual) + ctx}`; 29 | } 30 | 31 | static stringify(x: any): string { 32 | try { // handle circular references 33 | return JSON.stringify(x, (k, v) => { 34 | if (typeof v === 'function') { return `[${getFunctionName(v)}, Function]`; } // handle functions 35 | if (v instanceof RegExp) { return `[${String(v)}, RegExp]`; } // handle regexps 36 | return v; 37 | }, 2); 38 | } catch (e) {} 39 | return String(x); 40 | } 41 | 42 | } 43 | 44 | class Type { 45 | 46 | name: string; 47 | validate: ValidationFunction; 48 | 49 | constructor(name: string, validate: ValidationFunction) { 50 | this.name = name; 51 | this.validate = validate; 52 | } 53 | 54 | is(x: any): boolean { 55 | return this.validate(x, null, true) === null; 56 | } 57 | 58 | } 59 | 60 | function define(name: string, is: Predicate): Type { 61 | var type: Type = new Type(name, (x, ctx) => { 62 | return is(x) ? null : [new Failure(x, type, ctx)]; 63 | }); 64 | return type; 65 | } 66 | 67 | var Any = define('any', () => true); 68 | 69 | var Mixed = define('mixed', () => true); 70 | 71 | var Void = define('void', (x) => x === void 0); 72 | 73 | var Str = define('string', (x) => typeof x === 'string'); 74 | 75 | var Num = define('number', (x) => typeof x === 'number'); 76 | 77 | var Bool = define('boolean', (x) => x === true || x === false); 78 | 79 | var Arr = define('array', (x) => x instanceof Array); 80 | 81 | var Obj = define('object', (x) => x !== null && x !== undefined && typeof x === 'object' && !Arr.is(x)); 82 | 83 | var Func = define('function', (x) => typeof x === 'function'); 84 | 85 | function validate(x: any, type: any, ctx?: ?ValidationContext, failOnFirstError?: boolean) { 86 | if (type.validate) { 87 | return type.validate(x, ctx, failOnFirstError); 88 | } 89 | return x instanceof type ? null : [new Failure(x, type, ctx)]; 90 | } 91 | 92 | function list(type: Type, name?: string): Type { 93 | name = name || `Array<${type.name}>`; 94 | return new Type(name, (x, ctx, failOnFirstError) => { 95 | ctx = ctx || []; 96 | ctx.push(name); 97 | // if x is not an array, fail fast 98 | if (!Arr.is(x)) { return [new Failure(x, Arr, ctx)]; } 99 | var errors: ?Array = null, suberrors: ?Array; 100 | for (var i = 0, len = x.length ; i < len ; i++ ) { 101 | suberrors = validate(x[i], type, ctx.concat(i)); 102 | if (suberrors) { 103 | if (failOnFirstError) { return suberrors; } 104 | errors = errors || []; 105 | errors.push.apply(errors, suberrors); 106 | } 107 | } 108 | return errors; 109 | }); 110 | } 111 | 112 | function optional(type: Type, name?: string): Type { 113 | name = name || `${type.name}?`; 114 | return new Type(name, (x, ctx, failOnFirstError) => { 115 | if (x === void 0) { return null; } 116 | ctx = ctx || []; 117 | ctx.push(name); 118 | return validate(x, type, ctx, failOnFirstError); 119 | }); 120 | } 121 | 122 | function maybe(type: Type, name?: string): Type { 123 | name = name || `?${type.name}`; 124 | return new Type(name, (x, ctx, failOnFirstError) => { 125 | if (x === null) { return null; } 126 | ctx = ctx || []; 127 | ctx.push(name); 128 | return validate(x, type, ctx, failOnFirstError); 129 | }); 130 | } 131 | 132 | function getName(type: Type): string { 133 | return type.name; 134 | } 135 | 136 | function tuple(types: Array, name?: string): Type { 137 | name = name || `[${types.map(getName).join(', ')}]`; 138 | var dimension = types.length; 139 | var type: Type = new Type(name, (x, ctx, failOnFirstError) => { 140 | ctx = ctx || []; 141 | // if x is not an array, fail fast 142 | if (!Arr.is(x)) { return [new Failure(x, Arr, ctx.concat(name))]; } 143 | // if x has a wrong length, fail failOnFirstError 144 | if (x.length !== dimension) { return [new Failure(x, type, ctx)]; } 145 | var errors: ?Array = null, suberrors: ?Array; 146 | for (var i = 0 ; i < dimension ; i++ ) { 147 | suberrors = validate(x[i], types[i], ctx.concat(name, i)); 148 | if (suberrors) { 149 | if (failOnFirstError) { return suberrors; } 150 | errors = errors || []; 151 | errors.push.apply(errors, suberrors); 152 | } 153 | } 154 | return errors; 155 | }); 156 | return type; 157 | } 158 | 159 | function dict(domain: Type, codomain: Type, name?: string): Type { 160 | name = name || `{[key: ${domain.name}]: ${codomain.name}}`; 161 | return new Type(name, (x, ctx, failOnFirstError) => { 162 | ctx = ctx || []; 163 | // if x is not an object, fail fast 164 | if (!Obj.is(x)) { return [new Failure(x, Obj, ctx.concat(name))]; } 165 | var errors: ?Array = null, suberrors: ?Array; 166 | for (var k in x) { 167 | if (x.hasOwnProperty(k)) { 168 | // check domain 169 | suberrors = validate(k, domain, ctx.concat(name, k)); 170 | if (suberrors) { 171 | if (failOnFirstError) { return suberrors; } 172 | errors = errors || []; 173 | errors.push.apply(errors, suberrors); 174 | } 175 | // check codomain 176 | suberrors = validate(x[k], codomain, ctx.concat(name, k)); 177 | if (suberrors) { 178 | if (failOnFirstError) { return suberrors; } 179 | errors = errors || []; 180 | errors.push.apply(errors, suberrors); 181 | } 182 | } 183 | } 184 | return errors; 185 | }); 186 | } 187 | 188 | function shape(props: {[key: string]: Type;}, name?: string): Type { 189 | name = name || `{${Object.keys(props).map(function (k) { return k + ': ' + props[k].name + ';';}).join(' ')}}`; 190 | return new Type(name, (x, ctx, failOnFirstError) => { 191 | ctx = ctx || []; 192 | // if x is not an object, fail fast 193 | if (!Obj.is(x)) { return [new Failure(x, Obj, ctx.concat(name))]; } 194 | var errors: ?Array = null, suberrors: ?Array; 195 | for (var k in props) { 196 | if (props.hasOwnProperty(k)) { 197 | suberrors = validate(x[k], props[k], ctx.concat(name, k)); 198 | if (suberrors) { 199 | if (failOnFirstError) { return suberrors; } 200 | errors = errors || []; 201 | errors.push.apply(errors, suberrors); 202 | } 203 | } 204 | } 205 | return errors; 206 | }); 207 | } 208 | 209 | function union(types: Array, name?: string): Type { 210 | name = name || types.map(getName).join(' | '); 211 | var type: Type = new Type(name, (x, ctx) => { 212 | ctx = (ctx || []).concat(name); 213 | if (types.some((type) => validate(x, type, ctx, true) === null)) { return null; } 214 | return [new Failure(x, type, ctx)]; 215 | }); 216 | return type; 217 | } 218 | 219 | function slice(arr: Array, start?: number, end?: number): Array { 220 | return Array.prototype.slice.call(arr, start, end); 221 | } 222 | 223 | function args(types: Array, varargs?: Type): Type { 224 | var name = `(${types.map(getName).join(', ')}, ...${(varargs || Any).name})`; 225 | var length = types.length; 226 | var typesTuple = tuple(types); 227 | if (varargs) { varargs = list(varargs); } 228 | return new Type(name, (x, ctx, failOnFirstError) => { 229 | ctx = ctx || []; 230 | var args = x; 231 | // test if args is an array-like structure 232 | if (args.hasOwnProperty('length')) { 233 | args = slice(args, 0, length); 234 | // handle optional arguments filling the array with undefined values 235 | if (args.length < length) { args.length = length; } 236 | } 237 | var errors: ?Array = null, suberrors: ?Array; 238 | suberrors = typesTuple.validate(args, ctx.concat('arguments'), failOnFirstError); 239 | if (suberrors) { 240 | if (failOnFirstError) { return suberrors; } 241 | errors = errors || []; 242 | errors.push.apply(errors, suberrors); 243 | } 244 | if (varargs) { 245 | suberrors = varargs.validate(slice(x, length), ctx.concat('varargs'), failOnFirstError); 246 | if (suberrors) { 247 | if (failOnFirstError) { return suberrors; } 248 | errors = errors || []; 249 | errors.push.apply(errors, suberrors); 250 | } 251 | } 252 | return errors; 253 | }); 254 | } 255 | 256 | function check(x: T, type: Type): T { 257 | var errors = validate(x, type); 258 | if (errors) { 259 | var message = [].concat(errors).join('\n'); 260 | throw new TypeError(message); 261 | } 262 | return x; 263 | } 264 | 265 | module.exports = { 266 | Failure, 267 | Type, 268 | define, 269 | any: Any, 270 | mixed: Mixed, 271 | 'void': Void, 272 | number: Num, 273 | string: Str, 274 | 'boolean': Bool, 275 | object: Obj, 276 | 'function': Func, 277 | list, 278 | optional, 279 | maybe, 280 | tuple, 281 | dict, 282 | shape, 283 | union, 284 | arguments: args, 285 | check 286 | }; 287 | -------------------------------------------------------------------------------- /test/assert.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var tape = require('tape'); 4 | var f = require('../assert'); 5 | 6 | tape('Failure.stringify', function (tape) { 7 | 8 | tape.plan(7); 9 | 10 | tape.strictEqual( 11 | f.Failure.stringify(1), 12 | '1', 13 | 'should stringify numbers' 14 | ); 15 | 16 | tape.strictEqual( 17 | f.Failure.stringify('a'), 18 | '"a"', 19 | 'should stringify strings' 20 | ); 21 | 22 | tape.strictEqual( 23 | f.Failure.stringify(true), 24 | 'true', 25 | 'should stringify booleans' 26 | ); 27 | 28 | tape.strictEqual( 29 | f.Failure.stringify({a: 1}), 30 | '{\n "a": 1\n}', 31 | 'should stringify objects' 32 | ); 33 | 34 | tape.strictEqual( 35 | f.Failure.stringify([1, 2, 3]), 36 | '[\n 1,\n 2,\n 3\n]', 37 | 'should stringify arrays' 38 | ); 39 | 40 | tape.strictEqual( 41 | f.Failure.stringify(Date), 42 | '"[Date, Function]"', 43 | 'should stringify functions' 44 | ); 45 | 46 | tape.strictEqual( 47 | f.Failure.stringify(/^a/), 48 | '"[/^a/, RegExp]"', 49 | 'should stringify regexps' 50 | ); 51 | 52 | }); 53 | 54 | tape('number', function (tape) { 55 | 56 | tape.plan(5); 57 | 58 | tape.strictEqual( 59 | f.number.is('a'), 60 | false, 61 | 'is() should return false if x is not a number' 62 | ); 63 | 64 | tape.strictEqual( 65 | f.number.validate('a') + '', 66 | 'Expected an instance of number got "a", (no context)', 67 | 'validate() should fail if x is not a number' 68 | ); 69 | 70 | tape.strictEqual( 71 | f.number.validate(1), 72 | null, 73 | 'validate() should succeed if x is a number' 74 | ); 75 | 76 | tape.strictEqual( 77 | f.number.validate(NaN), 78 | null, 79 | 'validate() should succeed if x is a NaN' 80 | ); 81 | 82 | tape.strictEqual( 83 | f.number.validate(Infinity), 84 | null, 85 | 'validate() should succeed if x is Infinity' 86 | ); 87 | 88 | }); 89 | 90 | tape('list()', function (tape) { 91 | 92 | tape.plan(6); 93 | 94 | tape.strictEqual( 95 | f.list(f.number).name, 96 | 'Array', 97 | 'should set a default name' 98 | ); 99 | 100 | tape.strictEqual( 101 | f.list(f.number, 'MyList').name, 102 | 'MyList', 103 | 'should set a specified name' 104 | ); 105 | 106 | tape.strictEqual( 107 | f.list(f.number).validate(1) + '', 108 | 'Expected an instance of array got 1, context: Array', 109 | 'should fail if x is not an array' 110 | ); 111 | 112 | tape.strictEqual( 113 | f.list(f.number).validate([1, 's']) + '', 114 | 'Expected an instance of number got "s", context: Array / 1', 115 | 'should fail if an element of x is not an instance of T' 116 | ); 117 | 118 | tape.strictEqual( 119 | f.list(f.number).validate([1, 2]), 120 | null, 121 | 'should succeed if x is a list of numbers' 122 | ); 123 | 124 | tape.strictEqual( 125 | f.list(Date).validate([new Date(), new Date()]), 126 | null, 127 | 'should succeed if x is a list of dates' 128 | ); 129 | 130 | }); 131 | 132 | tape('optional()', function (tape) { 133 | 134 | tape.plan(2); 135 | 136 | tape.strictEqual( 137 | f.optional(f.number).validate('s') + '', 138 | 'Expected an instance of number got "s", context: number?', 139 | 'should fail if x is not an instance of T' 140 | ); 141 | 142 | tape.strictEqual( 143 | f.optional(f.number).validate(undefined), 144 | null, 145 | 'should succeed if x is undefined' 146 | ); 147 | 148 | }); 149 | 150 | tape('maybe()', function (tape) { 151 | 152 | tape.plan(7); 153 | 154 | tape.strictEqual( 155 | f.maybe(f.number).name, 156 | '?number', 157 | 'should set a default name' 158 | ); 159 | 160 | tape.strictEqual( 161 | f.maybe(f.number, 'MyMaybe').name, 162 | 'MyMaybe', 163 | 'should set a specified name' 164 | ); 165 | 166 | tape.strictEqual( 167 | f.maybe(f.number).validate('s') + '', 168 | 'Expected an instance of number got "s", context: ?number', 169 | 'should fail if x is not an instance of T' 170 | ); 171 | 172 | tape.strictEqual( 173 | f.maybe(f.number).validate(null), 174 | null, 175 | 'should succeed if x is null' 176 | ); 177 | 178 | tape.strictEqual( 179 | f.maybe(f.number).validate(undefined) + '', 180 | 'Expected an instance of number got undefined, context: ?number', 181 | 'should fail if x is undefined' 182 | ); 183 | 184 | tape.strictEqual( 185 | f.maybe(f.number).validate(1), 186 | null, 187 | 'should succeed if x is an instance of number' 188 | ); 189 | 190 | tape.strictEqual( 191 | f.maybe(Date).validate(new Date()), 192 | null, 193 | 'should succeed if x is an instance of Date' 194 | ); 195 | 196 | }); 197 | 198 | tape('tuple()', function (tape) { 199 | 200 | tape.plan(6); 201 | 202 | tape.strictEqual( 203 | f.tuple([f.string, f.number]).name, 204 | '[string, number]', 205 | 'should set a default name' 206 | ); 207 | 208 | tape.strictEqual( 209 | f.tuple([f.string, f.number], 'MyTuple').name, 210 | 'MyTuple', 211 | 'should set a specified name' 212 | ); 213 | 214 | tape.strictEqual( 215 | f.tuple([f.string, f.number]).validate(1) + '', 216 | 'Expected an instance of array got 1, context: [string, number]', 217 | 'should fail if x is not an array' 218 | ); 219 | 220 | tape.strictEqual( 221 | f.tuple([f.string, f.number]).validate(['s']) + '', 222 | 'Expected an instance of [string, number] got [\n "s"\n], (no context)', 223 | 'should fail if x is an array with wrong length' 224 | ); 225 | 226 | tape.strictEqual( 227 | f.tuple([f.string, f.number]).validate([1, 2]) + '', 228 | 'Expected an instance of string got 1, context: [string, number] / 0', 229 | 'should fail if the i-th coordinate of x is not an instance of T[i]' 230 | ); 231 | 232 | tape.strictEqual( 233 | f.tuple([f.string, f.number]).validate(['s', 1]), 234 | null, 235 | 'should succeed if x is an instance of T' 236 | ); 237 | 238 | }); 239 | 240 | tape('dict()', function (tape) { 241 | 242 | tape.plan(5); 243 | 244 | tape.strictEqual( 245 | f.dict(f.string, f.number).name, 246 | '{[key: string]: number}', 247 | 'should set a default name' 248 | ); 249 | 250 | tape.strictEqual( 251 | f.dict(f.string, f.number, 'MyDict').name, 252 | 'MyDict', 253 | 'should set a specified name' 254 | ); 255 | 256 | tape.strictEqual( 257 | f.dict(f.string, f.number).validate(1) + '', 258 | 'Expected an instance of object got 1, context: {[key: string]: number}', 259 | 'should fail if x is not an object' 260 | ); 261 | 262 | /* FIXME 263 | tape.strictEqual( 264 | f.dict(f.string, f.number).validate({}) + '', 265 | '', 266 | 'should fail if a key of x is not an instance of domain' 267 | ); 268 | */ 269 | 270 | tape.strictEqual( 271 | f.dict(f.string, f.number).validate({a: 's'}) + '', 272 | 'Expected an instance of number got "s", context: {[key: string]: number} / a', 273 | 'should fail if a value of x is not an instance of codomain' 274 | ); 275 | 276 | tape.strictEqual( 277 | f.dict(f.string, f.number).validate({a: 1, b: 2}), 278 | null, 279 | 'should succeed if x is an instance of T' 280 | ); 281 | 282 | }); 283 | 284 | tape('shape()', function (tape) { 285 | 286 | tape.plan(7); 287 | 288 | tape.strictEqual( 289 | f.shape({a: f.number, b: f.string}).name, 290 | '{a: number; b: string;}', 291 | 'should set a default name' 292 | ); 293 | 294 | tape.strictEqual( 295 | f.shape({a: f.number, b: f.string}, 'MyObject').name, 296 | 'MyObject', 297 | 'should set a specified name' 298 | ); 299 | 300 | tape.strictEqual( 301 | f.shape({a: f.number, b: f.string}).validate(1) + '', 302 | 'Expected an instance of object got 1, context: {a: number; b: string;}', 303 | 'should fail if x is not an object' 304 | ); 305 | 306 | tape.strictEqual( 307 | f.shape({a: f.number, b: f.string}).validate({a: 1, b: 2}) + '', 308 | 'Expected an instance of string got 2, context: {a: number; b: string;} / b', 309 | 'should fail if a key k of x is not an instance of T[k]' 310 | ); 311 | 312 | tape.strictEqual( 313 | f.shape({a: f.maybe(f.number)}).validate({}) + '', 314 | 'Expected an instance of number got undefined, context: {a: ?number;} / a / ?number', 315 | 'should fail if a key is not specified' 316 | ); 317 | 318 | tape.strictEqual( 319 | f.shape({a: f.number, b: f.string}).validate({a: 1, b: 's'}), 320 | null, 321 | 'should succeed if x is an instance of T' 322 | ); 323 | 324 | tape.strictEqual( 325 | f.shape({a: f.number}).validate({a: 1, b: 's'}), 326 | null, 327 | 'should succeed if x owns an additional property' 328 | ); 329 | 330 | }); 331 | 332 | tape('union()', function (tape) { 333 | 334 | tape.plan(5); 335 | 336 | tape.strictEqual( 337 | f.union([f.string, f.number]).name, 338 | 'string | number', 339 | 'should set a default name' 340 | ); 341 | 342 | tape.strictEqual( 343 | f.union([f.string, f.number], 'MyUnion').name, 344 | 'MyUnion', 345 | 'should set a specified name' 346 | ); 347 | 348 | tape.strictEqual( 349 | f.union([f.string, f.number]).validate(false) + '', 350 | 'Expected an instance of string | number got false, context: string | number', 351 | 'should fail if x is not an instance of T' 352 | ); 353 | 354 | tape.strictEqual( 355 | f.union([f.string, f.number]).validate(1), 356 | null, 357 | 'should succeed if x is an instance of string or number' 358 | ); 359 | 360 | tape.strictEqual( 361 | f.union([f.string, Date]).validate(new Date()), 362 | null, 363 | 'should succeed if x is an instance of string or date' 364 | ); 365 | 366 | }); 367 | 368 | tape('arguments()', function (tape) { 369 | 370 | tape.plan(6); 371 | 372 | tape.strictEqual( 373 | f.arguments([f.number, f.string]).name, 374 | '(number, string, ...any)', 375 | 'should set a proper name when varargs is not specified' 376 | ); 377 | 378 | tape.strictEqual( 379 | f.arguments([f.number, f.string], f.boolean).name, 380 | '(number, string, ...boolean)', 381 | 'should set a proper name when varargs is specified' 382 | ); 383 | 384 | tape.test('should fail if x is not an instance of the arguments tuple', function (tape) { 385 | 386 | tape.plan(3); 387 | 388 | tape.strictEqual( 389 | f.arguments([f.string, f.number]).validate(1) + '', 390 | 'Expected an instance of array got 1, context: arguments / [string, number]' 391 | ); 392 | 393 | tape.strictEqual( 394 | f.arguments([f.string, f.number]).validate([]) + '', 395 | 'Expected an instance of string got undefined, context: arguments / [string, number] / 0,Expected an instance of number got undefined, context: arguments / [string, number] / 1' 396 | ); 397 | 398 | tape.strictEqual( 399 | f.arguments([f.string, f.number]).validate(['a']) + '', 400 | 'Expected an instance of number got undefined, context: arguments / [string, number] / 1' 401 | ); 402 | 403 | }); 404 | 405 | tape.test('should succeed if x is an instance of the arguments tuple', function (tape) { 406 | 407 | tape.plan(4); 408 | 409 | tape.strictEqual( 410 | f.arguments([f.string, f.number]).validate(['s', 1]), 411 | null 412 | ); 413 | 414 | tape.strictEqual( 415 | f.arguments([f.string, f.number]).validate(['s', 1, 2]), 416 | null 417 | ); 418 | 419 | tape.strictEqual( 420 | f.arguments([f.optional(f.number)]).validate([undefined]), 421 | null 422 | ); 423 | 424 | tape.strictEqual( 425 | f.arguments([f.optional(f.number)]).validate([]), 426 | null 427 | ); 428 | 429 | }); 430 | 431 | tape.strictEqual( 432 | f.arguments([], f.string).validate([1]) + '', 433 | 'Expected an instance of string got 1, context: varargs / Array / 0', 434 | 'should fail if x is not an instance of the varargs list' 435 | ); 436 | 437 | tape.strictEqual( 438 | f.arguments([], f.string).validate(['a', 'b']), 439 | null, 440 | 'should succeed if x is an instance of the varargs list' 441 | ); 442 | 443 | 444 | }); 445 | 446 | 447 | -------------------------------------------------------------------------------- /test/browserify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var tape = require('tape'); 4 | var browserify = require('browserify'); 5 | var reactify = require('reactify'); 6 | var babelify = require('babelify'); 7 | var flowcheck = require('../index'); 8 | 9 | function contains(tape, bundle, code) { 10 | bundle = bundle.toString(); 11 | tape.ok(bundle.indexOf(code) > -1, 'bundle should contain: ' + code); 12 | } 13 | 14 | tape('browserify', function (tape) { 15 | tape.plan(3); 16 | 17 | tape.test('should transform a file with reactify', function (tape) { 18 | tape.plan(2); 19 | browserify('./fixtures/main.js', {basedir: __dirname}) 20 | .transform(flowcheck, {skipImport: true}) 21 | .transform(reactify, { 22 | stripTypes: true 23 | }) 24 | .bundle(function(err, result) { 25 | tape.ok(!err, 'should not fail'); 26 | contains(tape, result, 'var x = _f.check(1, _f.string);'); 27 | }); 28 | }); 29 | 30 | tape.test('should transform a file with 6to5', function (tape) { 31 | tape.plan(2); 32 | browserify('./fixtures/main.js', {basedir: __dirname}) 33 | .transform(flowcheck, {skipImport: true}) 34 | .transform(babelify) 35 | .bundle(function(err, result) { 36 | tape.ok(!err, 'should not fail'); 37 | contains(tape, result, 'var x = _f.check(1, _f.string);'); 38 | }); 39 | }); 40 | 41 | tape.test('shouldn\'t die if requiring JSON', function (tape) { 42 | tape.plan(2); 43 | browserify('./fixtures/main.json', {basedir: __dirname}) 44 | .transform(flowcheck) 45 | .bundle(function(err, result) { 46 | tape.ok(!err, 'should not fail'); 47 | contains(tape, result, '{"a": 1}'); 48 | }); 49 | }); 50 | 51 | }); -------------------------------------------------------------------------------- /test/fixtures/main.js: -------------------------------------------------------------------------------- 1 | var x: string = 1; -------------------------------------------------------------------------------- /test/fixtures/main.json: -------------------------------------------------------------------------------- 1 | {"a": 1} -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | require('./assert'); 2 | require('./visitors'); 3 | require('./browserify'); -------------------------------------------------------------------------------- /test/visitors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var tape = require('tape'); 4 | var originalTransform = require('../transform').transform; 5 | 6 | var transform = function (input) { 7 | return originalTransform(input, { 8 | skipImport: true 9 | }); 10 | }; 11 | 12 | tape('options', function (tape) { 13 | 14 | tape.plan(3); 15 | 16 | tape.strictEqual( 17 | originalTransform('var x: string = "a";', {namespace: 't', skipImport: true}), 18 | 'var x: string = t.check("a", t.string);', 19 | 'should handle namespace option' 20 | ); 21 | 22 | tape.strictEqual( 23 | originalTransform('var x: number = 1;', {module: 'a/b'}), 24 | 'var _f = require("a/b");var x: number = _f.check(1, _f.number);', 25 | 'should handle module option' 26 | ); 27 | 28 | tape.strictEqual( 29 | originalTransform('var x: boolean = true;', {target: 'es3', skipImport: true}), 30 | 'var x: boolean = _f.check(true, _f["boolean"]);', 31 | 'should handle target option' 32 | ); 33 | 34 | }); 35 | 36 | tape('variables', function (tape) { 37 | tape.plan(7); 38 | 39 | tape.strictEqual( 40 | transform('var x: string = "a";'), 41 | 'var x: string = _f.check("a", _f.string);', 42 | 'string type' 43 | ); 44 | 45 | tape.strictEqual( 46 | transform('var x: number = 1;'), 47 | 'var x: number = _f.check(1, _f.number);', 48 | 'number type' 49 | ); 50 | 51 | tape.strictEqual( 52 | transform('var x: boolean = true;'), 53 | 'var x: boolean = _f.check(true, _f.boolean);', 54 | 'boolean type' 55 | ); 56 | 57 | tape.strictEqual( 58 | transform('var x: void = undefined;'), 59 | 'var x: void = _f.check(undefined, _f.void);', 60 | 'void type' 61 | ); 62 | 63 | tape.strictEqual( 64 | transform('var x: mixed = null;'), 65 | 'var x: mixed = _f.check(null, _f.mixed);', 66 | 'mixed type' 67 | ); 68 | 69 | tape.strictEqual( 70 | transform('var x: Object = null;'), 71 | 'var x: Object = _f.check(null, _f.object);', 72 | 'Object type' 73 | ); 74 | 75 | tape.strictEqual( 76 | transform('var x: Function = null;'), 77 | 'var x: Function = _f.check(null, _f.function);', 78 | 'Function type' 79 | ); 80 | 81 | }); 82 | 83 | tape('lists', function (tape) { 84 | tape.plan(4); 85 | 86 | tape.strictEqual( 87 | transform('var x: Array = [\'a\'];'), 88 | 'var x: Array = _f.check([\'a\'], _f.list(_f.any));', 89 | 'Array' 90 | ); 91 | 92 | tape.strictEqual( 93 | transform('var x: string[] = [];'), 94 | 'var x: string[] = _f.check([], _f.list(_f.string));', 95 | 'array type ([] syntax)' 96 | ); 97 | 98 | tape.strictEqual( 99 | transform('var x: Array = [];'), 100 | 'var x: Array = _f.check([], _f.list(_f.string));', 101 | 'array type (Array<> syntax)' 102 | ); 103 | 104 | tape.throws(function () { 105 | transform('var a: Array = [];'); 106 | }, 'should throw if there are more than 1 type parameter'); 107 | 108 | }); 109 | 110 | tape('maybe types', function (tape) { 111 | tape.plan(1); 112 | 113 | tape.strictEqual( 114 | transform('var x: ?string = null;'), 115 | 'var x: ?string = _f.check(null, _f.maybe(_f.string));', 116 | 'should handle a nullable type' 117 | ); 118 | 119 | }); 120 | 121 | tape('optional types', function (tape) { 122 | tape.plan(1); 123 | 124 | tape.strictEqual( 125 | transform('function foo(a?: string) {}'), 126 | 'function foo(a?: string) {_f.check(arguments, _f.arguments([_f.optional(_f.string)]));}', 127 | 'should handle an optional function parameter' 128 | ); 129 | 130 | }); 131 | 132 | tape('dictionaries', function (tape) { 133 | tape.plan(1); 134 | 135 | tape.strictEqual( 136 | transform('var x: {[key: string]: number} = {a: 1, b: 2};'), 137 | 'var x: {[key: string]: number} = _f.check({a: 1, b: 2}, _f.dict(_f.string, _f.number));', 138 | 'should handle dictionaries' 139 | ); 140 | 141 | }); 142 | 143 | tape('shapes', function (tape) { 144 | tape.plan(3); 145 | 146 | tape.strictEqual( 147 | transform('var x: {} = {};'), 148 | 'var x: {} = _f.check({}, _f.shape({}));', 149 | 'should handle empty shapes' 150 | ); 151 | 152 | tape.strictEqual( 153 | transform('var x: {a: string; b: number;} = {};'), 154 | 'var x: {a: string; b: number;} = _f.check({}, _f.shape({a: _f.string, b: _f.number}));', 155 | 'should handle shapes' 156 | ); 157 | 158 | tape.strictEqual( 159 | transform('type MyType = {"foo-bar": number;};'), 160 | 'type MyType = {"foo-bar": number;};var MyType = _f.shape({"foo-bar": _f.number});', 161 | 'should escape literal keys' 162 | ); 163 | 164 | }); 165 | 166 | tape('tuples', function (tape) { 167 | tape.plan(1); 168 | 169 | tape.strictEqual( 170 | transform('var x: [string, number] = [];'), 171 | 'var x: [string, number] = _f.check([], _f.tuple([_f.string, _f.number]));', 172 | 'tuple' 173 | ); 174 | 175 | }); 176 | 177 | tape('unions', function (tape) { 178 | tape.plan(1); 179 | 180 | tape.strictEqual( 181 | transform('var x: string | number = 1;'), 182 | 'var x: string | number = _f.check(1, _f.union([_f.string, _f.number]));', 183 | 'union' 184 | ); 185 | 186 | }); 187 | 188 | tape('functions', function (tape) { 189 | tape.plan(11); 190 | 191 | tape.strictEqual( 192 | transform('function fn(s) { return s; } // comment'), 193 | 'function fn(s) { return s; } // comment', 194 | 'should handle not typed functions' 195 | ); 196 | 197 | tape.strictEqual( 198 | transform('function f(x: number) { var y: number = 1; } // comment'), 199 | 'function f(x: number) {_f.check(arguments, _f.arguments([_f.number])); var y: number = _f.check(1, _f.number); } // comment', 200 | 'should traverse the function body when arguments are types (#11)' 201 | ); 202 | 203 | tape.strictEqual( 204 | transform('function fn(s: string) { return s; } // comment'), 205 | 'function fn(s: string) {_f.check(arguments, _f.arguments([_f.string])); return s; } // comment', 206 | 'definition, only arguments' 207 | ); 208 | 209 | tape.strictEqual( 210 | transform('function fn(s: string): string { return s; } // comment'), 211 | 'function fn(s: string): string {_f.check(arguments, _f.arguments([_f.string])); var ret = (function (s) { return s; }).apply(this, arguments); return _f.check(ret, _f.string);} // comment', 212 | 'definition, arguments and return type' 213 | ); 214 | 215 | tape.strictEqual( 216 | transform('var fn = function (n: number) { return n; }; // comment'), 217 | 'var fn = function (n: number) {_f.check(arguments, _f.arguments([_f.number])); return n; }; // comment', 218 | 'expression, only arguments' 219 | ); 220 | 221 | tape.strictEqual( 222 | transform('var fn = function (n: number): number { return n; }; // comment'), 223 | 'var fn = function (n: number): number {_f.check(arguments, _f.arguments([_f.number])); var ret = (function (n) { return n; }).apply(this, arguments); return _f.check(ret, _f.number);}; // comment', 224 | 'expression, arguments and return type' 225 | ); 226 | 227 | tape.strictEqual( 228 | transform('var fn = function (...n: number): number { return 1; }; // comment'), 229 | 'var fn = function (...n: number): number {_f.check(arguments, _f.arguments([], _f.number)); var ret = (function () { return 1; }).apply(this, arguments); return _f.check(ret, _f.number);}; // comment', 230 | 'expression, varargs' 231 | ); 232 | 233 | tape.strictEqual( 234 | transform('var n: number = (function (n: number) { return n; })(1); // comment'), 235 | 'var n: number = _f.check((function (n: number) {_f.check(arguments, _f.arguments([_f.number])); return n; })(1), _f.number); // comment', 236 | 'called expression' 237 | ); 238 | 239 | tape.strictEqual( 240 | transform('function bar(...w: number) {}'), 241 | 'function bar(...w: number) {_f.check(arguments, _f.arguments([], _f.number));}', 242 | 'variadic' 243 | ); 244 | 245 | tape.strictEqual( 246 | transform('function map(fn: (x: T) => U) {}'), 247 | 'function map(fn: (x: T) => U) {_f.check(arguments, _f.arguments([_f.function]));}', 248 | 'should convert a generic function to the function type' 249 | ); 250 | 251 | tape.strictEqual( 252 | transform('function foo(x: T) { return x; }'), 253 | 'function foo(x: T) {_f.check(arguments, _f.arguments([_f.any])); return x; }', 254 | 'should handle polymorphic functions' 255 | ); 256 | 257 | }); 258 | 259 | tape('type alias', function (tape) { 260 | tape.plan(2); 261 | 262 | tape.strictEqual( 263 | transform('type X = Array;'), 264 | 'type X = Array;var X = _f.list(_f.number);', 265 | 'basic' 266 | ); 267 | 268 | tape.strictEqual( 269 | transform('type X = A;'), 270 | 'type X = A;var X = A;', 271 | 'generics' 272 | ); 273 | 274 | }); 275 | 276 | tape('classes', function (tape) { 277 | tape.plan(1); 278 | 279 | tape.strictEqual( 280 | transform('class C { foo(x: X): X { this.x = x; } }'), 281 | 'class C { foo(x: X): X {_f.check(arguments, _f.arguments([_f.any])); var ret = (function (x) { this.x = x; }).apply(this, arguments); return _f.check(ret, _f.any);} }', 282 | 'should handle polymorphic classes' 283 | ); 284 | 285 | }); 286 | 287 | -------------------------------------------------------------------------------- /transform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var jstransform = require('jstransform'); 4 | var visitorList = require('./visitors').visitorList; 5 | var Buffer = require('buffer').Buffer; 6 | 7 | function getOptions(options) { 8 | options = options || {}; 9 | options.namespace = options.namespace || '_f'; 10 | options.sourceMap = options['source-map'] || options.sourceMap; 11 | options.module = options.module || 'flowcheck/assert'; 12 | options.skipImport = options['skip-import'] || options.skipImport; 13 | return options; 14 | } 15 | 16 | function innerTransform(input, options) { 17 | return jstransform.transform(visitorList, input, getOptions(options)); 18 | } 19 | 20 | function inlineSourceMap(sourceMap, sourceCode, sourceFilename) { 21 | var json = sourceMap.toJSON(); 22 | json.sources = [sourceFilename]; 23 | json.sourcesContent = [sourceCode]; 24 | var base64 = new Buffer(JSON.stringify(json)).toString('base64'); 25 | return '//# sourceMappingURL=data:application/json;base64,' + 26 | base64; 27 | } 28 | 29 | module.exports = { 30 | 31 | transform: function(input, options) { 32 | var output = innerTransform(input, options); 33 | var result = output.code; 34 | if (options && options.sourceMap) { 35 | var map = inlineSourceMap( 36 | output.sourceMap, 37 | input, 38 | options.sourceFilename 39 | ); 40 | result += '\n' + map; 41 | } 42 | return result; 43 | }, 44 | 45 | transformWithDetails: function(input, options) { 46 | var output = innerTransform(input, options); 47 | var result = {}; 48 | result.code = output.code; 49 | if (options && options.sourceMap) { 50 | result.sourceMap = output.sourceMap.toJSON(); 51 | } 52 | return result; 53 | } 54 | 55 | }; 56 | -------------------------------------------------------------------------------- /visitors.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var jstransform = require('jstransform'); 4 | var utils = require('jstransform/src/utils'); 5 | 6 | var Syntax = jstransform.Syntax; 7 | 8 | // 9 | // utils 10 | // 11 | 12 | function getName(x) { 13 | return x.name; 14 | } 15 | 16 | function getObjectKey(key) { 17 | switch (key.type) { 18 | case Syntax.Identifier : 19 | return key.name; 20 | case Syntax.Literal : 21 | return JSON.stringify(key.value); 22 | } 23 | } 24 | 25 | function getParentClassDeclaration(path) { 26 | for (var i = 0, len = path.length ; i < len ; i++ ) { 27 | if (path[i].type === Syntax.ClassDeclaration) { 28 | return path[i]; 29 | } 30 | } 31 | return null; 32 | } 33 | 34 | function mixin(a, b) { 35 | for (var k in b) { 36 | if (b.hasOwnProperty(k)) { 37 | a[k] = b[k]; 38 | } 39 | } 40 | return a; 41 | } 42 | 43 | function toLookup(arr) { 44 | var lookup = {}; 45 | for (var i = 0, len = arr.length ; i < len ; i++ ) { 46 | lookup[arr[i]] = true; 47 | } 48 | return lookup; 49 | } 50 | 51 | // 52 | // Context 53 | // 54 | 55 | function Context(state, generics) { 56 | this.state = state; 57 | this.generics = generics; 58 | this.namespace = state.g.opts.namespace; 59 | this.target = state.g.opts.target; 60 | this.module = state.g.opts.module; 61 | this.skipImport = state.g.opts.skipImport; 62 | } 63 | 64 | Context.prototype.getProperty = function(name) { 65 | return this.target === 'es3' && name in {'void': 1, 'boolean': 1} ? // compatibility with ES3 66 | this.namespace + '[' + JSON.stringify(name) + ']' : 67 | this.namespace + '.' + name; 68 | }; 69 | 70 | Context.prototype.getNodeText = function(node) { 71 | return utils.getNodeSourceText(node, this.state) + 72 | ', line: ' + node.loc.start.line + 73 | ', column: ' + node.loc.start.column; 74 | }; 75 | 76 | Context.prototype.getType = function(ann) { 77 | if (ann) { 78 | switch (ann.type) { 79 | case Syntax.StringTypeAnnotation : 80 | return this.getProperty('string'); 81 | case Syntax.NumberTypeAnnotation : 82 | return this.getProperty('number'); 83 | case Syntax.BooleanTypeAnnotation : 84 | return this.getProperty('boolean'); 85 | case Syntax.AnyTypeAnnotation : 86 | return this.getProperty('any'); 87 | case Syntax.VoidTypeAnnotation : 88 | return this.getProperty('void'); 89 | 90 | case Syntax.NullableTypeAnnotation : 91 | // handle `?T` 92 | return this.getProperty('maybe') + '(' + this.getType(ann.typeAnnotation) + ')'; 93 | 94 | case Syntax.ArrayTypeAnnotation : 95 | // handle `T[]` 96 | return this.getProperty('list') + '(' + this.getType(ann.elementType) + ')'; 97 | 98 | case Syntax.GenericTypeAnnotation : 99 | if (ann.id.type === Syntax.Identifier) { 100 | var name = ann.id.name; 101 | // handle `mixed` type 102 | if (name === 'mixed') { 103 | return this.getProperty('mixed'); 104 | } 105 | // handle `Object` type 106 | if (name === 'Object') { 107 | return this.getProperty('object'); 108 | } 109 | // handle `Function` type 110 | if (name === 'Function') { 111 | return this.getProperty('function'); 112 | } 113 | if (name === 'Array') { 114 | // handle `Array` 115 | if (!ann.typeParameters) { 116 | return this.getProperty('list') + '(' + this.getProperty('any') + ')'; 117 | } 118 | // handle `Array` 119 | var atp = ann.typeParameters.params; 120 | if (atp.length !== 1) { 121 | throw new Error('invalid Array declaration ' + this.getNodeText(ann) + ' expected only one type parameter'); 122 | } 123 | return this.getProperty('list') + '(' + this.getType(atp[0]) + ')'; 124 | } 125 | // handle generics e.g. `function foo(x: T) { return x; }` 126 | // must print `f.arguments([f.any])` not `f.arguments([T])` 127 | if (!this.generics || !this.generics.hasOwnProperty(name)) { 128 | return name; 129 | } 130 | } 131 | break; 132 | 133 | case Syntax.TupleTypeAnnotation : 134 | // handle `[T1, T2, ... , Tn]` 135 | return this.getProperty('tuple') + '([' + ann.types.map(function (type) { 136 | return this.getType(type); 137 | }.bind(this)).join(', ') + '])'; 138 | 139 | case Syntax.ObjectTypeAnnotation : 140 | if (ann.indexers && ann.indexers[0]) { 141 | // handle `{[key: D]: C}` 142 | var domain = this.getType(ann.indexers[0].key); 143 | var codomain = this.getType(ann.indexers[0].value); 144 | return this.getProperty('dict') + '(' + domain + ', ' + codomain + ')'; 145 | } 146 | // handle `{p1: T1; p2: T2; ... pn: Tn;}` 147 | return this.getProperty('shape') + '({' + ann.properties.map(function (prop) { 148 | return getObjectKey(prop.key) + ': ' + this.getType(prop.value); 149 | }.bind(this)).join(', ') + '})'; 150 | 151 | case Syntax.UnionTypeAnnotation : 152 | // handle `T1 | T2 | ... | Tn` 153 | return this.getProperty('union') + '([' + ann.types.map(function (type) { 154 | return this.getType(type); 155 | }.bind(this)).join(', ') + '])'; 156 | 157 | case Syntax.FunctionTypeAnnotation : 158 | // handle `(x: T) => U` 159 | return this.getProperty('function'); 160 | 161 | } 162 | } 163 | // fallback 164 | return this.getProperty('any'); 165 | }; 166 | 167 | // 168 | // handle variable declarations 169 | // 170 | 171 | function visitTypedVariableDeclarator(traverse, node, path, state) { 172 | var ctx = new Context(state); 173 | if (node.init) { 174 | utils.catchup(node.init.range[0], state); 175 | utils.append(ctx.getProperty('check') + '(', state); 176 | traverse(node.init, path, state); 177 | utils.catchup(node.init.range[1], state); 178 | utils.append(', ' + ctx.getType(node.id.typeAnnotation.typeAnnotation) + ')', state); 179 | } 180 | utils.catchup(node.range[1], state); 181 | return false; 182 | } 183 | visitTypedVariableDeclarator.test = function(node) { 184 | return node.type === Syntax.VariableDeclarator && 185 | node.id.typeAnnotation; 186 | }; 187 | 188 | // 189 | // handle typed functions 190 | // a typed function is a function such that at least one param or the return value is typed 191 | // 192 | 193 | function visitTypedFunction(traverse, node, path, state) { 194 | var klass = getParentClassDeclaration(path); 195 | var generics = klass && klass.typeParameters ? toLookup(klass.typeParameters.params.map(getName)) : {}; 196 | if (node.typeParameters) { 197 | generics = mixin(generics, toLookup(node.typeParameters.params.map(getName))); 198 | } 199 | var ctx = new Context(state, generics); 200 | var rest = node.rest ? ', ' + ctx.getType(node.rest.typeAnnotation.typeAnnotation) : ''; 201 | var types = []; 202 | var params = []; 203 | node.params.forEach(function (param) { 204 | var type = ctx.getType(param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null); 205 | types.push(param.optional ? ctx.getProperty('optional') + '(' + type + ')' : type); 206 | params.push(param.name); 207 | }); 208 | 209 | utils.catchup(node.body.range[0] + 1, state); 210 | 211 | if (params.length || rest) { 212 | utils.append(ctx.getProperty('check') + '(arguments, ' + ctx.getProperty('arguments') + '([' + types.join(', ') + ']' + rest + '));', state); 213 | } 214 | 215 | if (node.returnType) { 216 | var returnType = ctx.getType(node.returnType.typeAnnotation); 217 | utils.append(' var ret = (function (' + params.join(', ') + ') {', state); 218 | traverse(node.body, path, state); 219 | utils.catchup(node.body.range[1] - 1, state); 220 | utils.append('}).apply(this, arguments); return ' + ctx.getProperty('check') + '(ret, ' + returnType + ');', state); 221 | } else { 222 | traverse(node.body, path, state); 223 | } 224 | 225 | return false; 226 | } 227 | visitTypedFunction.test = function(node) { 228 | return (node.type === Syntax.FunctionDeclaration || node.type === Syntax.FunctionExpression) && 229 | ( 230 | node.returnType || 231 | (node.rest && node.rest.typeAnnotation) || 232 | node.params.some(function (param) { return !!param.typeAnnotation; }) 233 | ); 234 | }; 235 | 236 | // 237 | // handle type aliases 238 | // 239 | 240 | function visitTypeAlias(traverse, node, path, state) { 241 | var ctx = new Context(state); 242 | utils.catchup(node.range[1], state); 243 | utils.append('var ' + node.id.name + ' = ' + ctx.getType(node.right) + ';', state); 244 | return false; 245 | } 246 | visitTypeAlias.test = function (node) { 247 | return node.type === Syntax.TypeAlias; 248 | }; 249 | 250 | function visitProgram(traverse, node, path, state) { 251 | var ctx = new Context(state); 252 | var namespace = ctx.namespace; 253 | // FIXME remove 2nd condition when flowcheck-loader will not use the namespace option 254 | if (!ctx.skipImport && namespace.indexOf('require') === -1) { 255 | utils.append('var ' + namespace + ' = require(' + JSON.stringify(ctx.module) + ');', state); 256 | } 257 | return true; 258 | } 259 | visitProgram.test = function (node) { 260 | return node.type === Syntax.Program; 261 | }; 262 | 263 | /* 264 | // experimental interface support 265 | function visitInterface(traverse, node, path, state) { 266 | console.log(node); 267 | var ctx = new Context(state); 268 | utils.catchup(node.range[1], state); 269 | utils.append('var ' + node.id.name + ' = ' + ctx.getType(node.body) + ';', state); 270 | return false; 271 | } 272 | visitInterface.test = function (node, path, state) { 273 | return node.type === Syntax.InterfaceDeclaration; 274 | }; 275 | */ 276 | 277 | module.exports = { 278 | visitorList: [ 279 | visitProgram, 280 | visitTypedFunction, 281 | visitTypedVariableDeclarator, 282 | visitTypeAlias 283 | //, visitInterface 284 | ] 285 | }; 286 | --------------------------------------------------------------------------------