geostats 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +13 -0
- data/README.md +58 -0
- data/bin/geostats +33 -0
- data/lib/geostats.rb +36 -0
- data/lib/geostats/commands/base.rb +73 -0
- data/lib/geostats/commands/console.rb +17 -0
- data/lib/geostats/commands/generate.rb +21 -0
- data/lib/geostats/commands/help.rb +20 -0
- data/lib/geostats/commands/init.rb +31 -0
- data/lib/geostats/commands/migrate.rb +21 -0
- data/lib/geostats/commands/push.rb +41 -0
- data/lib/geostats/commands/set.rb +35 -0
- data/lib/geostats/commands/update.rb +175 -0
- data/lib/geostats/console.rb +2 -0
- data/lib/geostats/core_ext.rb +5 -0
- data/lib/geostats/database.rb +15 -0
- data/lib/geostats/generator.rb +43 -0
- data/lib/geostats/grabber/cache.rb +95 -0
- data/lib/geostats/grabber/log.rb +27 -0
- data/lib/geostats/grabber/logs.rb +37 -0
- data/lib/geostats/grabber/user.rb +15 -0
- data/lib/geostats/http.rb +97 -0
- data/lib/geostats/migrations/001_create_caches.rb +27 -0
- data/lib/geostats/migrations/002_create_cache_types.rb +16 -0
- data/lib/geostats/migrations/003_create_logs.rb +13 -0
- data/lib/geostats/migrations/004_create_log_types.rb +15 -0
- data/lib/geostats/migrations/005_create_settings.rb +9 -0
- data/lib/geostats/migrations/006_add_cito_cache_type.rb +5 -0
- data/lib/geostats/models/cache.rb +47 -0
- data/lib/geostats/models/cache_type.rb +9 -0
- data/lib/geostats/models/log.rb +33 -0
- data/lib/geostats/models/log_type.rb +9 -0
- data/lib/geostats/models/setting.rb +16 -0
- data/lib/geostats/stats.rb +220 -0
- data/lib/geostats/templates/default.mustache +10 -0
- data/lib/geostats/templates/difficulty_terrain_matrix.mustache +40 -0
- data/lib/geostats/templates/founds_by_cache_type.mustache +17 -0
- data/lib/geostats/templates/milestones.mustache +19 -0
- data/lib/geostats/templates/monthly_founds.mustache +18 -0
- data/lib/geostats/templates/stylesheet.css +160 -0
- data/lib/geostats/utils.rb +42 -0
- data/lib/geostats/version.rb +3 -0
- data/lib/geostats/views/base.rb +19 -0
- data/lib/geostats/views/default.rb +13 -0
- data/lib/geostats/views/difficulty_terrain_matrix.rb +34 -0
- data/lib/geostats/views/founds_by_cache_type.rb +24 -0
- data/lib/geostats/views/milestones.rb +23 -0
- data/lib/geostats/views/monthly_founds.rb +24 -0
- metadata +165 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Log < ActiveRecord::Base
|
3
|
+
belongs_to :cache, :class_name => "Geostats::Cache"
|
4
|
+
belongs_to :log_type, :class_name => "Geostats::LogType"
|
5
|
+
|
6
|
+
scope :found_or_attended, lambda { where("logs.log_type_id IN (?)", [1, 12]) }
|
7
|
+
|
8
|
+
def self.create_from_website(uuid)
|
9
|
+
log = Log.new(:uuid => uuid)
|
10
|
+
log.update_from_website
|
11
|
+
log
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_from_website
|
15
|
+
info = Grabber::Log.new(self.uuid)
|
16
|
+
|
17
|
+
[:logged_at, :message].each do |attribute|
|
18
|
+
if value = info.send(attribute)
|
19
|
+
self.attributes = { attribute => value }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
set_type_from_icon(info.icon)
|
24
|
+
self.synced_at = Time.now
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_type_from_icon(icon)
|
28
|
+
if icon and index = LogType::ICON_MAPPING.index(icon)
|
29
|
+
self.log_type = LogType.where(:id => index + 1).first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Geostats
|
2
|
+
class LogType < ActiveRecord::Base
|
3
|
+
has_many :logs, :class_name => "Geostats::Log"
|
4
|
+
|
5
|
+
ICON_MAPPING = %w(icon_smile icon_sad icon_note icon_XXX icon_needsmaint
|
6
|
+
traffic_cone icon_enabled icon_disabled coord_update XXX icon_rsvp
|
7
|
+
icon_attended)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Setting < ActiveRecord::Base
|
3
|
+
validates :key, :presence => true, :uniqueness => true
|
4
|
+
|
5
|
+
def self.get(key)
|
6
|
+
setting = where(:key => key.to_s).first
|
7
|
+
setting ? setting.value : nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.set(key, value)
|
11
|
+
setting = where(:key => key.to_s).first || new(:key => key.to_s)
|
12
|
+
setting.update_attribute(:value, value)
|
13
|
+
setting
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
module Geostats
|
2
|
+
class Stats
|
3
|
+
class << self
|
4
|
+
def milestones(step=nil)
|
5
|
+
logs = Log
|
6
|
+
.joins(:cache)
|
7
|
+
.found_or_attended
|
8
|
+
.order("logs.logged_at ASC")
|
9
|
+
.all
|
10
|
+
total = logs.length
|
11
|
+
milestones = []
|
12
|
+
|
13
|
+
step ||= case total
|
14
|
+
when 0 then 0
|
15
|
+
when 1..100 then 50
|
16
|
+
when 101..1000 then 100
|
17
|
+
else 500
|
18
|
+
end
|
19
|
+
|
20
|
+
milestones << { :milestone => 1, :log => logs.first }
|
21
|
+
|
22
|
+
1.upto(total / step) do |i|
|
23
|
+
i *= step
|
24
|
+
log = logs[i - 1]
|
25
|
+
|
26
|
+
milestones << {
|
27
|
+
:milestone => i,
|
28
|
+
:log => logs[i - 1],
|
29
|
+
:distance => (log.logged_at - milestones.last[:log].logged_at) / 60 / 60 / 24
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
milestones << {
|
34
|
+
:milestone => total,
|
35
|
+
:log => logs.last,
|
36
|
+
:distance => (logs.last.logged_at - milestones.last[:log].logged_at) / 60 / 60 / 24
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_founds
|
41
|
+
Cache
|
42
|
+
.joins(:logs)
|
43
|
+
.found_or_attended
|
44
|
+
.count
|
45
|
+
end
|
46
|
+
|
47
|
+
def caching_days
|
48
|
+
Cache
|
49
|
+
.joins(:logs)
|
50
|
+
.found_or_attended
|
51
|
+
.group("logs.logged_at")
|
52
|
+
.count
|
53
|
+
.length
|
54
|
+
end
|
55
|
+
|
56
|
+
def avg_founds_per_caching_day
|
57
|
+
Cache
|
58
|
+
.joins(:logs)
|
59
|
+
.found_or_attended
|
60
|
+
.group("logs.logged_at")
|
61
|
+
.count
|
62
|
+
.to_a
|
63
|
+
.map { |a| a[1] }
|
64
|
+
.avg
|
65
|
+
end
|
66
|
+
|
67
|
+
def monthly_founds(months=6)
|
68
|
+
beginning_of_current_month = Time.parse("#{Time.now.strftime("%Y-%m")}-01")
|
69
|
+
|
70
|
+
0.upto(months - 1).map do |x|
|
71
|
+
start = beginning_of_current_month - x.months
|
72
|
+
count = Cache
|
73
|
+
.joins(:logs)
|
74
|
+
.found_or_attended
|
75
|
+
.where("logs.logged_at >= ? AND logs.logged_at < ?", start, start + 1.month)
|
76
|
+
.count
|
77
|
+
|
78
|
+
[start, count]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def daily_founds(days=30)
|
83
|
+
today = Time.parse(Time.now.strftime("%Y-%m-%d"))
|
84
|
+
|
85
|
+
1.upto(days).map do |x|
|
86
|
+
day = today - x.days
|
87
|
+
|
88
|
+
Cache
|
89
|
+
.joins(:logs)
|
90
|
+
.found_or_attended
|
91
|
+
.where("logs.logged_at >= ? AND logs.logged_at < ?", day, day + 1.day)
|
92
|
+
.count
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def day_with_most_founds
|
97
|
+
@day_with_most_founds ||= Cache
|
98
|
+
.joins(:logs)
|
99
|
+
.found_or_attended
|
100
|
+
.group("logs.logged_at")
|
101
|
+
.count
|
102
|
+
.to_a
|
103
|
+
.sort { |a, b| a[1] <=> b[1] }
|
104
|
+
.last
|
105
|
+
end
|
106
|
+
|
107
|
+
def founds_by_cache_type
|
108
|
+
CacheType.all.map do |type|
|
109
|
+
count = Cache
|
110
|
+
.joins(:logs)
|
111
|
+
.found_or_attended
|
112
|
+
.where("caches.cache_type_id = ?", type.id)
|
113
|
+
.count
|
114
|
+
|
115
|
+
[type, count]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def newest_cache
|
120
|
+
@newest_cache ||= Cache
|
121
|
+
.joins(:logs)
|
122
|
+
.found_or_attended
|
123
|
+
.order("caches.hidden_at DESC")
|
124
|
+
.first
|
125
|
+
end
|
126
|
+
|
127
|
+
def oldest_cache
|
128
|
+
@oldest_cache ||= Cache
|
129
|
+
.joins(:logs)
|
130
|
+
.found_or_attended
|
131
|
+
.order("caches.hidden_at ASC")
|
132
|
+
.first
|
133
|
+
end
|
134
|
+
|
135
|
+
def cache_with_most_founds
|
136
|
+
@cache_with_most_founds ||= Cache
|
137
|
+
.joins(:logs)
|
138
|
+
.found_or_attended
|
139
|
+
.order("caches.founds_count DESC")
|
140
|
+
.first
|
141
|
+
end
|
142
|
+
|
143
|
+
def cache_with_most_dnf
|
144
|
+
@cache_with_most_dnf ||= Cache
|
145
|
+
.joins(:logs)
|
146
|
+
.found_or_attended
|
147
|
+
.order("caches.dnf_count DESC")
|
148
|
+
.first
|
149
|
+
end
|
150
|
+
|
151
|
+
def archived_total_ratio
|
152
|
+
@archived_total_ratio ||= begin
|
153
|
+
archived = Cache
|
154
|
+
.joins(:logs)
|
155
|
+
.found_or_attended
|
156
|
+
.where("caches.is_archived = ?", true)
|
157
|
+
.count
|
158
|
+
|
159
|
+
total = Cache
|
160
|
+
.joins(:logs)
|
161
|
+
.found_or_attended
|
162
|
+
.count
|
163
|
+
|
164
|
+
{
|
165
|
+
:archived => archived,
|
166
|
+
:total => total,
|
167
|
+
:percentage => (archived.to_f / total.to_f * 100.0).round
|
168
|
+
}
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def most_northerly_cache
|
173
|
+
@most_northerly_cache ||= Cache
|
174
|
+
.joins(:logs)
|
175
|
+
.found_or_attended
|
176
|
+
.order("caches.latitude DESC")
|
177
|
+
.first
|
178
|
+
end
|
179
|
+
|
180
|
+
def most_southerly_cache
|
181
|
+
@most_southerly_cache ||= Cache
|
182
|
+
.joins(:logs)
|
183
|
+
.found_or_attended
|
184
|
+
.order("caches.latitude ASC")
|
185
|
+
.first
|
186
|
+
end
|
187
|
+
|
188
|
+
def most_westerly_cache
|
189
|
+
@most_westerly_cache ||= Cache
|
190
|
+
.joins(:logs)
|
191
|
+
.found_or_attended
|
192
|
+
.order("caches.longitude ASC")
|
193
|
+
.first
|
194
|
+
end
|
195
|
+
|
196
|
+
def most_easterly_cache
|
197
|
+
@most_easterly_cache ||= Cache
|
198
|
+
.joins(:logs)
|
199
|
+
.found_or_attended
|
200
|
+
.order("caches.longitude DESC")
|
201
|
+
.first
|
202
|
+
end
|
203
|
+
|
204
|
+
def difficulty_terrain_matrix
|
205
|
+
[1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].map do |difficulty|
|
206
|
+
result = Cache
|
207
|
+
.joins(:logs)
|
208
|
+
.found_or_attended
|
209
|
+
.where("caches.difficulty = ?", difficulty)
|
210
|
+
.group(:terrain)
|
211
|
+
.count
|
212
|
+
|
213
|
+
[1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5].map do |terrain|
|
214
|
+
result[terrain.to_f] || 0
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<div id="geostats">
|
2
|
+
{{{monthly_founds}}}
|
3
|
+
{{{founds_by_cache_type}}}
|
4
|
+
{{{milestones}}}
|
5
|
+
{{{difficulty_terrain_matrix}}}
|
6
|
+
<div id="about" class="box shadow">
|
7
|
+
Statistics generated on {{generation_date}} using
|
8
|
+
<a href="http://nano.github.com/geostats">geostats {{geostats_version}}</a>
|
9
|
+
</div>
|
10
|
+
</div>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<div id="difficulty-terrain-matrix" class="box">
|
2
|
+
<h2>Difficulty Terrain Matrix</h2>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<td width="9%"></td>
|
6
|
+
<td width="9%" class="label">T1</td>
|
7
|
+
<td width="9%" class="label">T1.5</td>
|
8
|
+
<td width="9%" class="label">T2</td>
|
9
|
+
<td width="9%" class="label">T2.5</td>
|
10
|
+
<td width="9%" class="label">T3</td>
|
11
|
+
<td width="9%" class="label">T3.5</td>
|
12
|
+
<td width="9%" class="label">T4</td>
|
13
|
+
<td width="9%" class="label">T4.5</td>
|
14
|
+
<td width="9%" class="label">T5</td>
|
15
|
+
<td width="9%"></td>
|
16
|
+
</tr>
|
17
|
+
{{#matrix}}
|
18
|
+
<tr>
|
19
|
+
<td class="label">D{{difficulty}}</td>
|
20
|
+
<td class="number">{{t1}}</td>
|
21
|
+
<td class="number">{{t15}}</td>
|
22
|
+
<td class="number">{{t2}}</td>
|
23
|
+
<td class="number">{{t25}}</td>
|
24
|
+
<td class="number">{{t3}}</td>
|
25
|
+
<td class="number">{{t35}}</td>
|
26
|
+
<td class="number">{{t4}}</td>
|
27
|
+
<td class="number">{{t45}}</td>
|
28
|
+
<td class="number">{{t5}}</td>
|
29
|
+
<td class="number sum">{{dsum}}</td>
|
30
|
+
</tr>
|
31
|
+
{{/matrix}}
|
32
|
+
<tr>
|
33
|
+
<td></td>
|
34
|
+
{{#tsums}}
|
35
|
+
<td class="number sum">{{sum}}</td>
|
36
|
+
{{/tsums}}
|
37
|
+
<td></td>
|
38
|
+
</tr>
|
39
|
+
</table>
|
40
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div id="founds-by-cache-type" class="box">
|
2
|
+
<h2>Founds By Cache Type</h2>
|
3
|
+
<div class="charts">
|
4
|
+
{{#founds_by_cache_type}}
|
5
|
+
<div class="section">
|
6
|
+
<div class="name">
|
7
|
+
{{name}}
|
8
|
+
</div>
|
9
|
+
<div class="chartbar" style="width: {{height}}px;"></div>
|
10
|
+
<div class="founds">
|
11
|
+
{{founds}}
|
12
|
+
</div>
|
13
|
+
<br style="clear: both;">
|
14
|
+
</div>
|
15
|
+
{{/founds_by_cache_type}}
|
16
|
+
</div>
|
17
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div id="milestones" class="box">
|
2
|
+
<h2>Milestones</h2>
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th></th>
|
6
|
+
<th align="left">Cache</th>
|
7
|
+
<th align="left">Date</th>
|
8
|
+
<th align="right">Distance in days</th>
|
9
|
+
</tr>
|
10
|
+
{{#milestones}}
|
11
|
+
<tr>
|
12
|
+
<td align="right" width="6%">{{milestone}}</td>
|
13
|
+
<td><a href="{{cache_url}}">{{name}}</a> ({{type}})</td>
|
14
|
+
<td width="16%"><a href="{{log_url}}">{{date}}</a></td>
|
15
|
+
<td align="right" width="16%">{{distance}}</td>
|
16
|
+
</tr>
|
17
|
+
{{/milestones}}
|
18
|
+
</table>
|
19
|
+
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div id="monthly-founds" class="box">
|
2
|
+
<h2>Founds By Month</h2>
|
3
|
+
<div class="charts">
|
4
|
+
{{#monthly_founds}}
|
5
|
+
<div class="section">
|
6
|
+
<div class="chartbox">
|
7
|
+
{{founds}}
|
8
|
+
<div class="chartbar" style="height: {{height}}px;"></div>
|
9
|
+
</div>
|
10
|
+
<div class="date">
|
11
|
+
{{month}}<br>
|
12
|
+
{{year}}
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
{{/monthly_founds}}
|
16
|
+
<br style="clear: both;">
|
17
|
+
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#geostats {
|
2
|
+
font: normal 13px Helvetica;
|
3
|
+
}
|
4
|
+
|
5
|
+
#geostats a {
|
6
|
+
color: rgb(19, 94, 196);
|
7
|
+
text-decoration: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
#geostats .box {
|
11
|
+
width: 700px;
|
12
|
+
background-color: #eee;
|
13
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e0e0e0));
|
14
|
+
-webkit-border-radius: 15px;
|
15
|
+
padding: 20px;
|
16
|
+
margin: 30px auto;
|
17
|
+
}
|
18
|
+
|
19
|
+
#geostats .box h2 {
|
20
|
+
color: rgb(19, 94, 196);
|
21
|
+
text-align: center;
|
22
|
+
text-shadow: #fff 1px 1px;
|
23
|
+
margin: 0 0 10px 0;
|
24
|
+
}
|
25
|
+
|
26
|
+
#geostats .shadow {
|
27
|
+
text-shadow: #fff 1px 1px;
|
28
|
+
color: #888;
|
29
|
+
}
|
30
|
+
|
31
|
+
#about {
|
32
|
+
text-align: center;
|
33
|
+
}
|
34
|
+
|
35
|
+
#milestones {
|
36
|
+
color: #777;
|
37
|
+
text-shadow: #fff 1px 1px;
|
38
|
+
}
|
39
|
+
|
40
|
+
#milestones table {
|
41
|
+
width: 100%;
|
42
|
+
border-spacing: 0;
|
43
|
+
padding: 0 20px;
|
44
|
+
}
|
45
|
+
|
46
|
+
#milestones td, #milestones th {
|
47
|
+
padding: 6px 10px;
|
48
|
+
}
|
49
|
+
|
50
|
+
#milestones th {
|
51
|
+
color: #999;
|
52
|
+
font-size: 11px;
|
53
|
+
font-weight: normal;
|
54
|
+
}
|
55
|
+
|
56
|
+
#founds-by-cache-type h2 {
|
57
|
+
color: rgb(210, 14, 14);
|
58
|
+
margin-bottom: 20px;
|
59
|
+
}
|
60
|
+
|
61
|
+
#founds-by-cache-type .charts {
|
62
|
+
width: 650px;
|
63
|
+
margin: auto;
|
64
|
+
}
|
65
|
+
|
66
|
+
#founds-by-cache-type .section {
|
67
|
+
margin: 10px 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
#founds-by-cache-type .chartbar {
|
71
|
+
float: left;
|
72
|
+
height: 20px;
|
73
|
+
background-color: rgb(210, 14, 14);
|
74
|
+
-webkit-border-top-right-radius: 4px;
|
75
|
+
-webkit-border-bottom-right-radius: 4px;
|
76
|
+
}
|
77
|
+
#founds-by-cache-type .founds {
|
78
|
+
float: left;
|
79
|
+
margin-left: 10px;
|
80
|
+
line-height: 20px;
|
81
|
+
color: rgb(210, 14, 14);
|
82
|
+
font-weight: bold;
|
83
|
+
}
|
84
|
+
|
85
|
+
#founds-by-cache-type .name {
|
86
|
+
float: left;
|
87
|
+
width: 180px;
|
88
|
+
margin-right: 20px;
|
89
|
+
color: #999;
|
90
|
+
text-align: right;
|
91
|
+
text-shadow: #fff 1px 1px;
|
92
|
+
line-height: 20px;
|
93
|
+
}
|
94
|
+
|
95
|
+
#monthly-founds .charts {
|
96
|
+
width: 672px;
|
97
|
+
margin: auto;
|
98
|
+
}
|
99
|
+
|
100
|
+
#monthly-founds .section {
|
101
|
+
float: left;
|
102
|
+
margin: 0 3px;
|
103
|
+
}
|
104
|
+
|
105
|
+
#monthly-founds .chartbox {
|
106
|
+
display: table-cell;
|
107
|
+
vertical-align: bottom;
|
108
|
+
height: 160px;
|
109
|
+
text-align: center;
|
110
|
+
color: rgb(19, 94, 196);
|
111
|
+
font-weight: bold;
|
112
|
+
}
|
113
|
+
|
114
|
+
#monthly-founds .chartbar {
|
115
|
+
background-color: rgb(19, 94, 196);
|
116
|
+
width: 50px;
|
117
|
+
-webkit-border-top-right-radius: 6px 6px;
|
118
|
+
-webkit-border-top-left-radius: 6px 6px;
|
119
|
+
margin-top: 3px;
|
120
|
+
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
121
|
+
}
|
122
|
+
|
123
|
+
#monthly-founds .date {
|
124
|
+
color: #AAA;
|
125
|
+
text-align: center;
|
126
|
+
margin-top: 5px;
|
127
|
+
text-shadow: #FFF 1px 1px;
|
128
|
+
}
|
129
|
+
|
130
|
+
#difficulty-terrain-matrix h2 {
|
131
|
+
color: rgb(36, 191, 19);
|
132
|
+
margin-bottom: 20px;
|
133
|
+
}
|
134
|
+
|
135
|
+
#difficulty-terrain-matrix table {
|
136
|
+
width: 100%;
|
137
|
+
padding: 0 20px;
|
138
|
+
border-spacing: 2px;
|
139
|
+
font-size: 11px;
|
140
|
+
text-align: center;
|
141
|
+
}
|
142
|
+
|
143
|
+
#difficulty-terrain-matrix td.number,
|
144
|
+
#difficulty-terrain-matrix td.label,
|
145
|
+
#difficulty-terrain-matrix td.sum {
|
146
|
+
color: #fff;
|
147
|
+
text-shadow: #888 0px 1px;
|
148
|
+
-webkit-border-radius: 3px;
|
149
|
+
padding: 4px;
|
150
|
+
}
|
151
|
+
|
152
|
+
#difficulty-terrain-matrix td.number {
|
153
|
+
background-color: rgba(36, 191, 19, 0.75);
|
154
|
+
}
|
155
|
+
|
156
|
+
#difficulty-terrain-matrix td.label,
|
157
|
+
#difficulty-terrain-matrix td.sum {
|
158
|
+
font-weight: bold;
|
159
|
+
background-color: rgb(36, 191, 19);
|
160
|
+
}
|