redis-stat 0.3.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +85 -0
- data/Rakefile +8 -0
- data/bin/redis-stat +16 -0
- data/lib/redis-stat/constants.rb +118 -0
- data/lib/redis-stat/option.rb +134 -0
- data/lib/redis-stat/server/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/lib/redis-stat/server/public/bootstrap/css/bootstrap.min.css +9 -0
- data/lib/redis-stat/server/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/lib/redis-stat/server/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/lib/redis-stat/server/public/bootstrap/js/bootstrap.min.js +6 -0
- data/lib/redis-stat/server/public/css/site.css +67 -0
- data/lib/redis-stat/server/public/favicon.ico +0 -0
- data/lib/redis-stat/server/public/favicon.png +0 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasAxisLabelRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasAxisTickRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasTextRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jquery.jqplot.min.css +1 -0
- data/lib/redis-stat/server/public/jqplot/jquery.jqplot.min.js +57 -0
- data/lib/redis-stat/server/public/jquery-1.8.2.min.js +2 -0
- data/lib/redis-stat/server/public/js/site.js +192 -0
- data/lib/redis-stat/server/views/index.erb +145 -0
- data/lib/redis-stat/server.rb +57 -0
- data/lib/redis-stat/version.rb +3 -0
- data/lib/redis-stat.rb +314 -0
- data/redis-stat.gemspec +33 -0
- data/test/bin_helper.rb +9 -0
- data/test/test_redis-stat.rb +193 -0
- metadata +194 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Junegunn Choi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# redis-stat
|
2
|
+
|
3
|
+
_redis-stat_ is a simple Redis monitoring tool written in Ruby.
|
4
|
+
|
5
|
+
It is based on [INFO](http://redis.io/commands/info) command of Redis,
|
6
|
+
and thus generally won't affect the performance of the Redis instance
|
7
|
+
unlike the other monitoring tools based on [MONITOR](http://redis.io/commands/monitor) command.
|
8
|
+
|
9
|
+
_redis-stat_ allows you to monitor Redis instances
|
10
|
+
- either with vmstat-like output from the terminal
|
11
|
+
- or with the dashboard page served by its embedded web server.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```
|
16
|
+
gem install redis-stat
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```
|
22
|
+
usage: redis-stat [HOST[:PORT] ...] [INTERVAL [COUNT]]
|
23
|
+
|
24
|
+
-a, --auth=PASSWORD Password
|
25
|
+
-v, --verbose Show more info
|
26
|
+
--style=STYLE Output style: unicode|ascii
|
27
|
+
--no-color Suppress ANSI color codes
|
28
|
+
--csv=OUTPUT_CSV_FILE_PATH Save the result in CSV format
|
29
|
+
|
30
|
+
--server[=PORT] Launch redis-stat web server (default port: 63790)
|
31
|
+
--daemon Daemonize redis-stat. Must be used with --server option.
|
32
|
+
|
33
|
+
--version Show version
|
34
|
+
--help Show this message
|
35
|
+
```
|
36
|
+
|
37
|
+
## Running redis-stat for command-line monitoring
|
38
|
+
|
39
|
+
```
|
40
|
+
redis-stat
|
41
|
+
redis-stat 1
|
42
|
+
redis-stat 1 10
|
43
|
+
redis-stat --verbose
|
44
|
+
redis-stat localhost:6380 1 10
|
45
|
+
redis-stat localhost localhost:6380 localhost:6381 5
|
46
|
+
redis-stat localhost localhost:6380 1 10 --csv=/tmp/output.csv --verbose
|
47
|
+
```
|
48
|
+
|
49
|
+
### Screenshot
|
50
|
+
|
51
|
+
![Terminal output](https://github.com/junegunn/redis-stat/raw/master/screenshots/redis-stat-0.3.0.png)
|
52
|
+
|
53
|
+
## redis-stat in web browser
|
54
|
+
|
55
|
+
When `--server` option is set, redis-stat will open up an embedded web server (default port: 63790)
|
56
|
+
in the background so that you can monitor Redis in your browser.
|
57
|
+
|
58
|
+
Since _redis-stat_ pushes updates every interval via [Server-sent events](http://www.w3.org/TR/eventsource/),
|
59
|
+
modern browsers are required to view the page.
|
60
|
+
|
61
|
+
```
|
62
|
+
redis-stat --server
|
63
|
+
redis-stat --verbose --server=8080 5
|
64
|
+
|
65
|
+
# redis-stat server can be daemonized
|
66
|
+
redis-stat --server --daemon
|
67
|
+
```
|
68
|
+
|
69
|
+
### Screenshot
|
70
|
+
|
71
|
+
![Dashboard](https://github.com/junegunn/redis-stat/raw/master/screenshots/redis-stat-web.png)
|
72
|
+
|
73
|
+
## Author
|
74
|
+
- [Junegunn Choi](https://github.com/junegunn)
|
75
|
+
|
76
|
+
## Contributors
|
77
|
+
- [Chris Meisl](https://github.com/cmeisl)
|
78
|
+
|
79
|
+
## Contributing
|
80
|
+
|
81
|
+
1. Fork it
|
82
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
83
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
84
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
85
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/redis-stat
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redis-stat'
|
5
|
+
|
6
|
+
options = RedisStat::Option.parse ARGV
|
7
|
+
rs = RedisStat.new options
|
8
|
+
if options[:daemon]
|
9
|
+
require 'daemons'
|
10
|
+
Daemons.daemonize(:app_name => 'redis-stat-daemon')
|
11
|
+
end
|
12
|
+
begin
|
13
|
+
rs.start $stdout
|
14
|
+
rescue Exception
|
15
|
+
raise if options[:verbose]
|
16
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class RedisStat
|
2
|
+
DEFAULT_TERM_WIDTH = 180
|
3
|
+
DEFAULT_TERM_HEIGHT = 25
|
4
|
+
DEFAULT_SERVER_PORT = 63790
|
5
|
+
DEFAULT_REDIS_TIMEOUT = 30
|
6
|
+
|
7
|
+
MEASURES = {
|
8
|
+
:static => [
|
9
|
+
:redis_version,
|
10
|
+
:process_id,
|
11
|
+
:uptime_in_seconds,
|
12
|
+
:uptime_in_days,
|
13
|
+
:gcc_version,
|
14
|
+
:role,
|
15
|
+
:connected_slaves,
|
16
|
+
:aof_enabled,
|
17
|
+
:vm_enabled
|
18
|
+
],
|
19
|
+
:default => [
|
20
|
+
:at,
|
21
|
+
:used_cpu_user,
|
22
|
+
:used_cpu_sys,
|
23
|
+
:connected_clients,
|
24
|
+
:blocked_clients,
|
25
|
+
:used_memory,
|
26
|
+
:used_memory_rss,
|
27
|
+
:keys,
|
28
|
+
:total_commands_processed_per_second,
|
29
|
+
:expired_keys_per_second,
|
30
|
+
:evicted_keys_per_second,
|
31
|
+
:keyspace_hits_per_second,
|
32
|
+
:keyspace_misses_per_second,
|
33
|
+
:aof_current_size,
|
34
|
+
:pubsub_channels,
|
35
|
+
],
|
36
|
+
:verbose => [
|
37
|
+
:at,
|
38
|
+
:used_cpu_user,
|
39
|
+
:used_cpu_sys,
|
40
|
+
:connected_clients,
|
41
|
+
:blocked_clients,
|
42
|
+
:used_memory,
|
43
|
+
:used_memory_rss,
|
44
|
+
:mem_fragmentation_ratio,
|
45
|
+
:keys,
|
46
|
+
:total_commands_processed_per_second,
|
47
|
+
:total_commands_processed,
|
48
|
+
:expired_keys_per_second,
|
49
|
+
:expired_keys,
|
50
|
+
:evicted_keys_per_second,
|
51
|
+
:evicted_keys,
|
52
|
+
:keyspace_hits_per_second,
|
53
|
+
:keyspace_hits,
|
54
|
+
:keyspace_misses_per_second,
|
55
|
+
:keyspace_misses,
|
56
|
+
:aof_current_size,
|
57
|
+
:aof_base_size,
|
58
|
+
:changes_since_last_save,
|
59
|
+
:pubsub_channels,
|
60
|
+
:pubsub_patterns,
|
61
|
+
]
|
62
|
+
}
|
63
|
+
|
64
|
+
COLORS = {
|
65
|
+
:at => [:bold],
|
66
|
+
:used_cpu_user => [:yellow, :bold],
|
67
|
+
:used_cpu_sys => [:yellow],
|
68
|
+
:connected_clients => [:cyan, :bold],
|
69
|
+
:blocked_clients => [:cyan, :bold],
|
70
|
+
:used_memory => [:green],
|
71
|
+
:used_memory_rss => [:green],
|
72
|
+
:mem_fragmentation_ratio => [:green],
|
73
|
+
:keys => [:bold],
|
74
|
+
:total_commands_processed => [:blue, :bold],
|
75
|
+
:total_commands_processed_per_second => [:blue, :bold],
|
76
|
+
:expired_keys => [:red],
|
77
|
+
:expired_keys_per_second => [:red],
|
78
|
+
:evicted_keys => [:red, :bold],
|
79
|
+
:evicted_keys_per_second => [:red, :bold],
|
80
|
+
:keyspace_hits => [:magenta, :bold],
|
81
|
+
:keyspace_hits_per_second => [:magenta, :bold],
|
82
|
+
:keyspace_misses => [:magenta],
|
83
|
+
:keyspace_misses_per_second => [:magenta],
|
84
|
+
:aof_current_size => [:cyan],
|
85
|
+
:aof_base_size => [:cyan],
|
86
|
+
:changes_since_last_save => [:green, :bold],
|
87
|
+
:pubsub_channels => [:cyan, :bold],
|
88
|
+
:pubsub_patterns => [:cyan, :bold],
|
89
|
+
}
|
90
|
+
|
91
|
+
LABELS = {
|
92
|
+
:at => 'time',
|
93
|
+
:used_cpu_user => 'us',
|
94
|
+
:used_cpu_sys => 'sy',
|
95
|
+
:connected_clients => 'cl',
|
96
|
+
:blocked_clients => 'bcl',
|
97
|
+
:used_memory => 'mem',
|
98
|
+
:used_memory_rss => 'rss',
|
99
|
+
:mem_fragmentation_ratio => 'frag',
|
100
|
+
:total_commands_processed => 'cmd',
|
101
|
+
:total_commands_processed_per_second => 'cmd/s',
|
102
|
+
:expired_keys => 'exp',
|
103
|
+
:expired_keys_per_second => 'exp/s',
|
104
|
+
:evicted_keys => 'evt',
|
105
|
+
:evicted_keys_per_second => 'evt/s',
|
106
|
+
:keys => 'keys',
|
107
|
+
:keyspace_hits => 'hit',
|
108
|
+
:keyspace_hits_per_second => 'hit/s',
|
109
|
+
:keyspace_misses => 'mis',
|
110
|
+
:keyspace_misses_per_second => 'mis/s',
|
111
|
+
:aof_current_size => 'aofcs',
|
112
|
+
:aof_base_size => 'aofbs',
|
113
|
+
:changes_since_last_save => 'chsv',
|
114
|
+
:pubsub_channels => 'psch',
|
115
|
+
:pubsub_patterns => 'psp',
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
class RedisStat
|
4
|
+
module Option
|
5
|
+
DEFAULT = {
|
6
|
+
:hosts => ['127.0.0.1:6379'],
|
7
|
+
:interval => 2,
|
8
|
+
:count => nil,
|
9
|
+
:csv => nil,
|
10
|
+
:style => :unicode
|
11
|
+
}
|
12
|
+
|
13
|
+
def self.parse argv
|
14
|
+
argv = argv.reject { |e| e == '-h' }
|
15
|
+
|
16
|
+
options = DEFAULT.dup
|
17
|
+
opts = ::OptionParser.new { |opts|
|
18
|
+
opts.banner = "usage: redis-stat [HOST[:PORT] ...] [INTERVAL [COUNT]]"
|
19
|
+
opts.separator ''
|
20
|
+
|
21
|
+
opts.on('-a', '--auth=PASSWORD', 'Password') do |v|
|
22
|
+
options[:auth] = v
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-v', '--verbose', 'Show more info') do |v|
|
26
|
+
options[:verbose] = v
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on('--style=STYLE', 'Output style: unicode|ascii') do |v|
|
30
|
+
options[:style] = v.downcase.to_sym
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('--no-color', 'Suppress ANSI color codes') do |v|
|
34
|
+
options[:mono] = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('--csv=OUTPUT_CSV_FILE_PATH', 'Save the result in CSV format') do |v|
|
38
|
+
options[:csv] = v
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.separator ''
|
42
|
+
|
43
|
+
opts.on('--server[=PORT]', "Launch redis-stat web server (default port: #{RedisStat::DEFAULT_SERVER_PORT})") do |v|
|
44
|
+
options[:server_port] = v || RedisStat::DEFAULT_SERVER_PORT
|
45
|
+
if RUBY_PLATFORM == 'java'
|
46
|
+
raise ArgumentError.new("Sorry. redis-stat server is not supported in JRuby.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on('--daemon', "Daemonize redis-stat. Must be used with --server option.") do |v|
|
51
|
+
options[:daemon] = true
|
52
|
+
if RUBY_PLATFORM == 'java'
|
53
|
+
raise ArgumentError.new("Sorry. Daemonization is not supported in JRuby.")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.separator ''
|
58
|
+
|
59
|
+
opts.on('--version', 'Show version') do
|
60
|
+
puts RedisStat::VERSION
|
61
|
+
exit 0
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on_tail('--help', 'Show this message') do
|
65
|
+
puts opts
|
66
|
+
exit 0
|
67
|
+
end
|
68
|
+
}
|
69
|
+
|
70
|
+
begin
|
71
|
+
opts.parse! argv
|
72
|
+
|
73
|
+
is_number = lambda { |str| str =~ /^([0-9]\.?[0-9]*)$|^([1-9][0-9]*)$/ }
|
74
|
+
|
75
|
+
numbers, hosts = argv.partition { |e| is_number.call e }
|
76
|
+
interval, count = numbers.map(&:to_f)
|
77
|
+
|
78
|
+
options[:interval] = interval if interval
|
79
|
+
options[:count] = count if count
|
80
|
+
options[:hosts] = hosts unless hosts.empty?
|
81
|
+
|
82
|
+
validate options
|
83
|
+
|
84
|
+
return options
|
85
|
+
rescue SystemExit => e
|
86
|
+
exit e.status
|
87
|
+
rescue Exception => e
|
88
|
+
puts e.to_s
|
89
|
+
puts opts
|
90
|
+
exit 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.validate options
|
95
|
+
options[:interval].tap do |interval|
|
96
|
+
unless interval.is_a?(Numeric) && interval > 0
|
97
|
+
raise ArgumentError.new("Invalid interval: #{interval}")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
options[:count].tap do |count|
|
102
|
+
unless count.nil? || (count.is_a?(Numeric) && count > 0)
|
103
|
+
raise ArgumentError.new("Invalid count: #{count}")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
options[:hosts].tap do |hosts|
|
108
|
+
if hosts.empty?
|
109
|
+
raise ArgumentError.new("Redis host not given")
|
110
|
+
end
|
111
|
+
|
112
|
+
hosts.each do |host|
|
113
|
+
host, port = host.split(':')
|
114
|
+
if port
|
115
|
+
port = port.to_i
|
116
|
+
unless port > 0 && port < 65536
|
117
|
+
raise ArgumentError.new("Invalid port: #{port}")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
options[:style].tap do |style|
|
124
|
+
unless [:unicode, :ascii].include?(style)
|
125
|
+
raise ArgumentError.new("Invalid style")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if options[:daemon] && options[:server_port].nil?
|
130
|
+
raise ArgumentError.new("--daemon option must be used in conjunction with --server option")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/*!
|
2
|
+
* Bootstrap Responsive v2.1.1
|
3
|
+
*
|
4
|
+
* Copyright 2012 Twitter, Inc
|
5
|
+
* Licensed under the Apache License v2.0
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
*
|
8
|
+
* Designed and built with all the love in the world @twitter by @mdo and @fat.
|
9
|
+
*/.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade.in{top:auto}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
|