octogate 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/lib/octogate.rb +23 -0
  4. data/lib/octogate/client.rb +3 -0
  5. data/lib/octogate/events/base.rb +13 -0
  6. data/lib/octogate/events/issue.rb +0 -8
  7. data/lib/octogate/events/issue_comment.rb +0 -8
  8. data/lib/octogate/events/pull_request.rb +0 -8
  9. data/lib/octogate/events/pull_request_review_comment.rb +0 -8
  10. data/lib/octogate/events/push.rb +2 -2
  11. data/lib/octogate/sent_event.rb +25 -0
  12. data/lib/octogate/server.rb +39 -3
  13. data/lib/octogate/target_builder.rb +1 -0
  14. data/lib/octogate/version.rb +1 -1
  15. data/octogate.gemspec +2 -1
  16. data/spec/lib/octogate/client_spec.rb +1 -1
  17. data/spec/lib/octogate/events/issue_comment_spec.rb +1 -1
  18. data/spec/lib/octogate/events/issue_spec.rb +1 -1
  19. data/spec/lib/octogate/events/pull_request_review_comment_spec.rb +1 -1
  20. data/spec/lib/octogate/events/pull_request_spec.rb +1 -1
  21. data/spec/lib/octogate/events/push_spec.rb +1 -1
  22. data/web/assets/bootstrap/css/bootstrap-theme.css +347 -0
  23. data/web/assets/bootstrap/css/bootstrap-theme.css.map +1 -0
  24. data/web/assets/bootstrap/css/bootstrap-theme.min.css +7 -0
  25. data/web/assets/bootstrap/css/bootstrap.css +5785 -0
  26. data/web/assets/bootstrap/css/bootstrap.css.map +1 -0
  27. data/web/assets/bootstrap/css/bootstrap.min.css +7 -0
  28. data/web/assets/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  29. data/web/assets/bootstrap/fonts/glyphicons-halflings-regular.svg +229 -0
  30. data/web/assets/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  31. data/web/assets/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  32. data/web/assets/bootstrap/js/bootstrap.js +1951 -0
  33. data/web/assets/bootstrap/js/bootstrap.min.js +6 -0
  34. data/web/assets/javascripts/jquery-1.11.0.min.js +4 -0
  35. data/web/views/received_events.haml +22 -0
  36. data/web/views/sent_events.haml +45 -0
  37. metadata +41 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a893f768570f7934db01a2314d6467c7cd3f930a
4
- data.tar.gz: d9861197a5ceac6cb8b3916ce5d69ace77d80e18
3
+ metadata.gz: cbbcaafd61153f1ecf484accf96d55714aa639b8
4
+ data.tar.gz: f3f71fa90f84e4a3ac33d9f0a6d58cecb83a2a37
5
5
  SHA512:
6
- metadata.gz: 4f991d9e3c4f8fc28662af108b296a5c3fdd3b3f45b79fd010ede2aa65f66879f2c401998ce1e331b5358618e6a4fc851e0cbfa533c9f833610da5d15e914316
7
- data.tar.gz: e40e81224d97c31f4410888b5b2d6511a9af023736c51d2e776670e13b6fd63580be3e6d0746a3964847e17124718574dd971de4368b2a46a96d73aea2bccecb
6
+ metadata.gz: fc15590436c8a4d1b70069268f2799d922ed8e1898e72759c136d4307738b41895f73260fa8184383866cc3d6ce94acbca15705fd6faba76e99bb4b369d16d62
7
+ data.tar.gz: cd50a16df5e7af7b537546329156dc82bd06c761b970ec1fa5f85f0096ce9970de8f0066068e8627ae27379a9ae21d43a112918d5ca7f1a56036958944fc34b1
data/README.md CHANGED
@@ -93,6 +93,14 @@ Usage: octogate [options]
93
93
  # => Endpoint is http://hostname:4567/token_string
94
94
  ```
95
95
 
96
+ ## Routing
97
+
98
+ | URL | description |
99
+ | ----- | ----- |
100
+ | http://hostname:port/:token | Event Hook Endpoint |
101
+ | http://hostname:port/:token/received_events | View Received Events (Recently 100 Events from boot) |
102
+ | http://hostname:port/:token/sent_events | View Sent Events (Recently 100 Events from boot) |
103
+
96
104
  ## Config DSL Reference
97
105
 
98
106
  ### Global definitions
@@ -2,13 +2,17 @@ require "octogate/version"
2
2
 
3
3
  require "active_support/core_ext/hash"
4
4
  require "active_support/core_ext/object"
5
+ require "active_support/core_ext/string"
5
6
  require "oj"
6
7
  require "hashie"
8
+ require "awesome_print"
7
9
 
8
10
  require "octogate/configuration"
9
11
 
10
12
  module Octogate
11
13
  class << self
14
+ REC_LIMIT = 100
15
+
12
16
  def config
13
17
  @config ||= Configuration.instance
14
18
  end
@@ -16,6 +20,24 @@ module Octogate
16
20
  def find_target(key)
17
21
  @config.targets.fetch(key)
18
22
  end
23
+
24
+ def sent
25
+ @sent ||= []
26
+ end
27
+
28
+ def received
29
+ @received ||= []
30
+ end
31
+
32
+ def add_sent(target)
33
+ sent.pop if sent.length > REC_LIMIT
34
+ sent.unshift target
35
+ end
36
+
37
+ def add_received(event)
38
+ received.pop if received.length > REC_LIMIT
39
+ received.unshift event
40
+ end
19
41
  end
20
42
  end
21
43
 
@@ -25,4 +47,5 @@ require "octogate/config_loader"
25
47
  require "octogate/target"
26
48
  require "octogate/target_builder"
27
49
  require "octogate/events"
50
+ require "octogate/sent_event"
28
51
  require "octogate/gh"
@@ -37,6 +37,9 @@ class Octogate::Client
37
37
  Octogate::TransferRequest::POST.new(conn)
38
38
  .do_request(url: uri.path, params: params, parameter_type: target.parameter_type)
39
39
  end
40
+
41
+ sent_event = Octogate::SentEvent.build(event, target, params)
42
+ Octogate.add_sent(sent_event)
40
43
  end
41
44
 
42
45
  private
@@ -1,8 +1,21 @@
1
+ require "oj"
2
+
1
3
  module Octogate
2
4
  class Event::Base < Octogate::Model
3
5
  class << self
4
6
  def register_event(name, klass)
5
7
  Octogate::Event.register_event(name, klass)
8
+ self.instance_eval do
9
+ define_method :name do
10
+ name
11
+ end
12
+ end
13
+ end
14
+
15
+ def parse(delivery_id, json)
16
+ payload = Oj.load(json).deep_symbolize_keys
17
+
18
+ new(payload.merge(delivery_id: delivery_id))
6
19
  end
7
20
  end
8
21
 
@@ -8,13 +8,5 @@ module Octogate
8
8
  coerce_key :issue, GH::Issue
9
9
  coerce_key :repository, GH::Repository
10
10
  coerce_key :sender, GH::User
11
-
12
- class << self
13
- def parse(json)
14
- payload = Oj.load(json).deep_symbolize_keys
15
-
16
- new(payload)
17
- end
18
- end
19
11
  end
20
12
  end
@@ -9,13 +9,5 @@ module Octogate
9
9
  coerce_key :comment, GH::IssueComment
10
10
  coerce_key :repository, GH::Repository
11
11
  coerce_key :sender, GH::User
12
-
13
- class << self
14
- def parse(json)
15
- payload = Oj.load(json).deep_symbolize_keys
16
-
17
- new(payload)
18
- end
19
- end
20
12
  end
21
13
  end
@@ -9,14 +9,6 @@ module Octogate
9
9
  coerce_key :repository, GH::Repository
10
10
  coerce_key :sender, GH::User
11
11
 
12
- class << self
13
- def parse(json)
14
- payload = Oj.load(json).deep_symbolize_keys
15
-
16
- new(payload)
17
- end
18
- end
19
-
20
12
  def default_condition
21
13
  action != "closed"
22
14
  end
@@ -8,13 +8,5 @@ module Octogate
8
8
  coerce_key :comment, GH::ReviewComment
9
9
  coerce_key :repository, GH::Repository
10
10
  coerce_key :sender, GH::User
11
-
12
- class << self
13
- def parse(json)
14
- payload = Oj.load(json).deep_symbolize_keys
15
-
16
- new(payload)
17
- end
18
- end
19
11
  end
20
12
  end
@@ -9,14 +9,14 @@ module Octogate
9
9
  coerce_key :repository, GH::Repository
10
10
 
11
11
  class << self
12
- def parse(json)
12
+ def parse(delivery_id, json)
13
13
  payload = Oj.load(json).deep_symbolize_keys
14
14
 
15
15
  commits = payload[:commits].nil? ? [] : payload.delete(:commits).map do |c|
16
16
  GH::Commit.new(c.symbolize_keys)
17
17
  end
18
18
 
19
- attrs = payload.merge(commits: commits)
19
+ attrs = payload.merge(delivery_id: delivery_id, commits: commits)
20
20
 
21
21
  new(attrs)
22
22
  end
@@ -0,0 +1,25 @@
1
+ require "oj"
2
+
3
+ module Octogate
4
+ class SentEvent < Model
5
+ class << self
6
+ def build(event, target, params, sent_at = Time.now)
7
+ new(
8
+ event: event,
9
+ target_name: target.name,
10
+ target_url: target.url,
11
+ sent_payload: params,
12
+ sent_at: sent_at
13
+ )
14
+ end
15
+ end
16
+
17
+ def delivery_id
18
+ event.delivery_id
19
+ end
20
+
21
+ def name
22
+ event.name
23
+ end
24
+ end
25
+ end
@@ -1,10 +1,38 @@
1
1
  require "sinatra"
2
+ require "haml"
2
3
 
3
4
  class Octogate::Server < Sinatra::Base
5
+ set :root, File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "web")
6
+ set :public_folder, Proc.new { File.expand_path("#{root}/assets") }
7
+ set :views, Proc.new { "#{root}/views" }
8
+ set :haml, :format => :html5
9
+
4
10
  configure :production, :development do
5
11
  enable :logging
6
12
  end
7
13
 
14
+ get '/:token/received_events' do
15
+ unless Octogate.config.token == params[:token]
16
+ status 403
17
+ body "Access forbidden"
18
+ return
19
+ end
20
+
21
+ received = Octogate.received
22
+ haml :received_events, locals: {received: received}
23
+ end
24
+
25
+ get '/:token/sent_events' do
26
+ unless Octogate.config.token == params[:token]
27
+ status 403
28
+ body "Access forbidden"
29
+ return
30
+ end
31
+
32
+ sent = Octogate.sent
33
+ haml :sent_events, locals: {sent: sent}
34
+ end
35
+
8
36
  post '/:token' do
9
37
  unless Octogate.config.token == params[:token]
10
38
  status 403
@@ -12,11 +40,19 @@ class Octogate::Server < Sinatra::Base
12
40
  return
13
41
  end
14
42
 
15
- event_name = request.env["HTTP_X_GITHUB_EVENT"]
16
- event_klass = Octogate::Event.get(event_name)
17
- event = event_klass.parse(params[:payload])
43
+ event = build_event_from(request)
44
+ Octogate.add_received(event)
18
45
  Octogate::Client.new(event).request_to_targets
19
46
 
20
47
  return
21
48
  end
49
+
50
+ def build_event_from(request)
51
+ delivery_id = request.env["HTTP_X_GITHUB_DELIVERY"]
52
+ event_name = request.env["HTTP_X_GITHUB_EVENT"]
53
+ event_klass = Octogate::Event.get(event_name)
54
+ event = event_klass.parse(delivery_id, params[:payload])
55
+ event.received_at = Time.now
56
+ event
57
+ end
22
58
  end
@@ -47,6 +47,7 @@ module Octogate
47
47
 
48
48
  def __to_target__
49
49
  Target.new(
50
+ name: @name,
50
51
  url: @url,
51
52
  username: @username,
52
53
  password: @password,
@@ -1,3 +1,3 @@
1
1
  module Octogate
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -23,12 +23,13 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency "oj"
24
24
  spec.add_runtime_dependency "faraday"
25
25
  spec.add_runtime_dependency "hashie"
26
+ spec.add_runtime_dependency "haml"
27
+ spec.add_runtime_dependency "awesome_print"
26
28
 
27
29
  spec.add_development_dependency "bundler", ">= 1.5"
28
30
  spec.add_development_dependency "rake"
29
31
  spec.add_development_dependency "rspec"
30
32
  spec.add_development_dependency "tapp"
31
- spec.add_development_dependency "awesome_print"
32
33
  spec.add_development_dependency "webmock"
33
34
  spec.add_development_dependency "thin"
34
35
  spec.add_development_dependency "coveralls"
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Client do
4
4
  describe "#request_to_targets" do
5
- let(:event) { Octogate::Event::Push.parse(read_payload(:push)) }
5
+ let(:event) { Octogate::Event::Push.parse("delivery_id", read_payload(:push)) }
6
6
 
7
7
  before do
8
8
  stub_request(:post, "http://targethost.dev/job/JobName")
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Event::IssueComment do
4
4
  describe ".parse" do
5
- subject { described_class.parse(read_payload(:issue_comment)) }
5
+ subject { described_class.parse("delivery_id", read_payload(:issue_comment)) }
6
6
  it { should be_a described_class }
7
7
 
8
8
  it { expect(subject.action).to eq "created" }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Event::Issue do
4
4
  describe ".parse" do
5
- subject { described_class.parse(read_payload(:issues)) }
5
+ subject { described_class.parse("delivery_id", read_payload(:issues)) }
6
6
  it { should be_a described_class }
7
7
 
8
8
  it { expect(subject.action).to eq "opened" }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Event::PullRequestReviewComment do
4
4
  describe ".parse" do
5
- subject { described_class.parse(read_payload(:pull_request_review_comment)) }
5
+ subject { described_class.parse("delivery_id", read_payload(:pull_request_review_comment)) }
6
6
  it { should be_a described_class }
7
7
 
8
8
  it { expect(subject.comment).to be_a Octogate::GH::ReviewComment }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Event::PullRequest do
4
4
  describe ".parse" do
5
- subject { described_class.parse(read_payload(:pull_request)) }
5
+ subject { described_class.parse("delivery_id", read_payload(:pull_request)) }
6
6
  it { should be_a described_class }
7
7
 
8
8
  it { expect(subject.action).to eq "opened" }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Octogate::Event::Push do
4
4
  describe ".parse" do
5
- subject { described_class.parse(read_payload(:push)) }
5
+ subject { described_class.parse("delivery_id", read_payload(:push)) }
6
6
  it { should be_a described_class }
7
7
 
8
8
  it { expect(subject.ref).to eq "refs/heads/master" }
@@ -0,0 +1,347 @@
1
+ /*!
2
+ * Bootstrap v3.1.1 (http://getbootstrap.com)
3
+ * Copyright 2011-2014 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+
7
+ .btn-default,
8
+ .btn-primary,
9
+ .btn-success,
10
+ .btn-info,
11
+ .btn-warning,
12
+ .btn-danger {
13
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
14
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
15
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
16
+ }
17
+ .btn-default:active,
18
+ .btn-primary:active,
19
+ .btn-success:active,
20
+ .btn-info:active,
21
+ .btn-warning:active,
22
+ .btn-danger:active,
23
+ .btn-default.active,
24
+ .btn-primary.active,
25
+ .btn-success.active,
26
+ .btn-info.active,
27
+ .btn-warning.active,
28
+ .btn-danger.active {
29
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
30
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
31
+ }
32
+ .btn:active,
33
+ .btn.active {
34
+ background-image: none;
35
+ }
36
+ .btn-default {
37
+ text-shadow: 0 1px 0 #fff;
38
+ background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
39
+ background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
40
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
41
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
42
+ background-repeat: repeat-x;
43
+ border-color: #dbdbdb;
44
+ border-color: #ccc;
45
+ }
46
+ .btn-default:hover,
47
+ .btn-default:focus {
48
+ background-color: #e0e0e0;
49
+ background-position: 0 -15px;
50
+ }
51
+ .btn-default:active,
52
+ .btn-default.active {
53
+ background-color: #e0e0e0;
54
+ border-color: #dbdbdb;
55
+ }
56
+ .btn-primary {
57
+ background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
58
+ background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
59
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);
60
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
61
+ background-repeat: repeat-x;
62
+ border-color: #2b669a;
63
+ }
64
+ .btn-primary:hover,
65
+ .btn-primary:focus {
66
+ background-color: #2d6ca2;
67
+ background-position: 0 -15px;
68
+ }
69
+ .btn-primary:active,
70
+ .btn-primary.active {
71
+ background-color: #2d6ca2;
72
+ border-color: #2b669a;
73
+ }
74
+ .btn-success {
75
+ background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
76
+ background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
77
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
78
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
79
+ background-repeat: repeat-x;
80
+ border-color: #3e8f3e;
81
+ }
82
+ .btn-success:hover,
83
+ .btn-success:focus {
84
+ background-color: #419641;
85
+ background-position: 0 -15px;
86
+ }
87
+ .btn-success:active,
88
+ .btn-success.active {
89
+ background-color: #419641;
90
+ border-color: #3e8f3e;
91
+ }
92
+ .btn-info {
93
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
94
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
95
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
96
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
97
+ background-repeat: repeat-x;
98
+ border-color: #28a4c9;
99
+ }
100
+ .btn-info:hover,
101
+ .btn-info:focus {
102
+ background-color: #2aabd2;
103
+ background-position: 0 -15px;
104
+ }
105
+ .btn-info:active,
106
+ .btn-info.active {
107
+ background-color: #2aabd2;
108
+ border-color: #28a4c9;
109
+ }
110
+ .btn-warning {
111
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
112
+ background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
113
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
114
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
115
+ background-repeat: repeat-x;
116
+ border-color: #e38d13;
117
+ }
118
+ .btn-warning:hover,
119
+ .btn-warning:focus {
120
+ background-color: #eb9316;
121
+ background-position: 0 -15px;
122
+ }
123
+ .btn-warning:active,
124
+ .btn-warning.active {
125
+ background-color: #eb9316;
126
+ border-color: #e38d13;
127
+ }
128
+ .btn-danger {
129
+ background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
130
+ background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
131
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
132
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
133
+ background-repeat: repeat-x;
134
+ border-color: #b92c28;
135
+ }
136
+ .btn-danger:hover,
137
+ .btn-danger:focus {
138
+ background-color: #c12e2a;
139
+ background-position: 0 -15px;
140
+ }
141
+ .btn-danger:active,
142
+ .btn-danger.active {
143
+ background-color: #c12e2a;
144
+ border-color: #b92c28;
145
+ }
146
+ .thumbnail,
147
+ .img-thumbnail {
148
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
149
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
150
+ }
151
+ .dropdown-menu > li > a:hover,
152
+ .dropdown-menu > li > a:focus {
153
+ background-color: #e8e8e8;
154
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
155
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
156
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
157
+ background-repeat: repeat-x;
158
+ }
159
+ .dropdown-menu > .active > a,
160
+ .dropdown-menu > .active > a:hover,
161
+ .dropdown-menu > .active > a:focus {
162
+ background-color: #357ebd;
163
+ background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
164
+ background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
165
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
166
+ background-repeat: repeat-x;
167
+ }
168
+ .navbar-default {
169
+ background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
170
+ background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
171
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
172
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
173
+ background-repeat: repeat-x;
174
+ border-radius: 4px;
175
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
176
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
177
+ }
178
+ .navbar-default .navbar-nav > .active > a {
179
+ background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
180
+ background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
181
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);
182
+ background-repeat: repeat-x;
183
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
184
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
185
+ }
186
+ .navbar-brand,
187
+ .navbar-nav > li > a {
188
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
189
+ }
190
+ .navbar-inverse {
191
+ background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
192
+ background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
193
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
194
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
195
+ background-repeat: repeat-x;
196
+ }
197
+ .navbar-inverse .navbar-nav > .active > a {
198
+ background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
199
+ background-image: linear-gradient(to bottom, #222 0%, #282828 100%);
200
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);
201
+ background-repeat: repeat-x;
202
+ -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
203
+ box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
204
+ }
205
+ .navbar-inverse .navbar-brand,
206
+ .navbar-inverse .navbar-nav > li > a {
207
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
208
+ }
209
+ .navbar-static-top,
210
+ .navbar-fixed-top,
211
+ .navbar-fixed-bottom {
212
+ border-radius: 0;
213
+ }
214
+ .alert {
215
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
216
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
217
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
218
+ }
219
+ .alert-success {
220
+ background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
221
+ background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
222
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
223
+ background-repeat: repeat-x;
224
+ border-color: #b2dba1;
225
+ }
226
+ .alert-info {
227
+ background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
228
+ background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
229
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
230
+ background-repeat: repeat-x;
231
+ border-color: #9acfea;
232
+ }
233
+ .alert-warning {
234
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
235
+ background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
236
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
237
+ background-repeat: repeat-x;
238
+ border-color: #f5e79e;
239
+ }
240
+ .alert-danger {
241
+ background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
242
+ background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
243
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
244
+ background-repeat: repeat-x;
245
+ border-color: #dca7a7;
246
+ }
247
+ .progress {
248
+ background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
249
+ background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
250
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
251
+ background-repeat: repeat-x;
252
+ }
253
+ .progress-bar {
254
+ background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
255
+ background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
256
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);
257
+ background-repeat: repeat-x;
258
+ }
259
+ .progress-bar-success {
260
+ background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
261
+ background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
262
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
263
+ background-repeat: repeat-x;
264
+ }
265
+ .progress-bar-info {
266
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
267
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
268
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
269
+ background-repeat: repeat-x;
270
+ }
271
+ .progress-bar-warning {
272
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
273
+ background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
274
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
275
+ background-repeat: repeat-x;
276
+ }
277
+ .progress-bar-danger {
278
+ background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
279
+ background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
280
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
281
+ background-repeat: repeat-x;
282
+ }
283
+ .list-group {
284
+ border-radius: 4px;
285
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
286
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
287
+ }
288
+ .list-group-item.active,
289
+ .list-group-item.active:hover,
290
+ .list-group-item.active:focus {
291
+ text-shadow: 0 -1px 0 #3071a9;
292
+ background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
293
+ background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
294
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);
295
+ background-repeat: repeat-x;
296
+ border-color: #3278b3;
297
+ }
298
+ .panel {
299
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
300
+ box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
301
+ }
302
+ .panel-default > .panel-heading {
303
+ background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
304
+ background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
305
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
306
+ background-repeat: repeat-x;
307
+ }
308
+ .panel-primary > .panel-heading {
309
+ background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
310
+ background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
311
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);
312
+ background-repeat: repeat-x;
313
+ }
314
+ .panel-success > .panel-heading {
315
+ background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
316
+ background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
317
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
318
+ background-repeat: repeat-x;
319
+ }
320
+ .panel-info > .panel-heading {
321
+ background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
322
+ background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
323
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
324
+ background-repeat: repeat-x;
325
+ }
326
+ .panel-warning > .panel-heading {
327
+ background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
328
+ background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
329
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
330
+ background-repeat: repeat-x;
331
+ }
332
+ .panel-danger > .panel-heading {
333
+ background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
334
+ background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
335
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
336
+ background-repeat: repeat-x;
337
+ }
338
+ .well {
339
+ background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
340
+ background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
341
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
342
+ background-repeat: repeat-x;
343
+ border-color: #dcdcdc;
344
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
345
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
346
+ }
347
+ /*# sourceMappingURL=bootstrap-theme.css.map */