##// END OF EJS Templates
Update Views y several improvements
Juan C. Espinoza -
r316:0d39f71bbf42
parent child
Show More
@@ -1,12 +1,12
1 1 REDIS_HOST=radarsys-redis
2 2 REDIS_PORT=6379
3 3 POSTGRES_DB_NAME=radarsys
4 4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
5 5 POSTGRES_PORT_5432_TCP_PORT=5432
6 6 POSTGRES_USER=docker
7 7 POSTGRES_PASSWORD=docker
8 8 PGDATA=/var/lib/postgresql/data
9 9 LC_ALL=C.UTF-8
10 10 TZ=America/Lima
11 DOCKER_DATA=/data/dockers/radarsys/
11 DOCKER_DATA=/Volumes/dockers/radarsys/
12 12 LOCAL_IP=192.168.1.128
@@ -1,6 +1,7
1 1 migrations/
2 2 .DS_Store
3 3 *.sqlite
4 4 .vscode/
5 5 *.pyc
6 6 .env
7 remove_migrations.py
@@ -1,73 +1,75
1 1 from django import forms
2 2 from .models import ABSConfiguration, ABSBeam
3 3 from .widgets import UpDataWidget, DownDataWidget, EditUpDataWidget, EditDownDataWidget
4 4 from apps.main.models import Configuration
5 5 import os
6 6
7 7 class ABSConfigurationForm(forms.ModelForm):
8 8 def __init__(self, *args, **kwargs):
9 9 super(ABSConfigurationForm, self).__init__(*args, **kwargs)
10 10
11 11 class Meta:
12 12 model = ABSConfiguration
13 exclude = ('type', 'status', 'parameters', 'active_beam', 'module_status', 'module_messages', 'module_mode')
13 exclude = ('type', 'status', 'parameters', 'active_beam',
14 'module_status', 'module_messages', 'module_mode',
15 'author', 'hash')
14 16
15 17
16 18 class ABSBeamAddForm(forms.Form):
17 19
18 20 up_data = forms.CharField(widget=UpDataWidget, label='')
19 21 down_data = forms.CharField(widget=DownDataWidget, label='')
20 22
21 23 def __init__(self, *args, **kwargs):
22 24 super(ABSBeamAddForm, self).__init__(*args, **kwargs)
23 25
24 26
25 27
26 28 class ABSBeamEditForm(forms.Form):
27 29
28 30 up_data = forms.CharField(widget=EditUpDataWidget, label='')
29 31 down_data = forms.CharField(widget=EditDownDataWidget, label='')
30 32
31 33 def __init__(self, *args, **kwargs):
32 34 super(ABSBeamEditForm, self).__init__(*args, **kwargs)
33 35
34 36 if 'initial' in kwargs:
35 37 if 'beam' in self.initial:
36 38 self.fields['up_data'].initial = self.initial['beam']
37 39 self.fields['down_data'].initial = self.initial['beam']
38 40
39 41
40 42 class ExtFileField(forms.FileField):
41 43 """
42 44 Same as forms.FileField, but you can specify a file extension whitelist.
43 45
44 46 >>> from django.core.files.uploadedfile import SimpleUploadedFile
45 47 >>>
46 48 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
47 49 >>>
48 50 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
49 51 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
50 52 >>>
51 53 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
52 54 Traceback (most recent call last):
53 55 ...
54 56 ValidationError: [u'Not allowed filetype!']
55 57 """
56 58 def __init__(self, *args, **kwargs):
57 59 extensions = kwargs.pop("extensions")
58 60 self.extensions = [i.lower() for i in extensions]
59 61
60 62 super(ExtFileField, self).__init__(*args, **kwargs)
61 63
62 64 def clean(self, *args, **kwargs):
63 65 data = super(ExtFileField, self).clean(*args, **kwargs)
64 66 filename = data.name
65 67 ext = os.path.splitext(filename)[1]
66 68 ext = ext.lower()
67 69 if ext not in self.extensions:
68 70 raise forms.ValidationError('Not allowed file type: %s' % ext)
69 71
70 72
71 73 class ABSImportForm(forms.Form):
72 74
73 75 file_name = ExtFileField(extensions=['.json'])
@@ -1,864 +1,864
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 from django.core.urlresolvers import reverse
4 4 # Create your models here.
5 5 from celery.execute import send_task
6 6 from datetime import datetime
7 7 import ast
8 8 import socket
9 9 import json
10 10 import requests
11 11 import struct
12 12 import os, sys, time
13 13
14 14 import multiprocessing
15 15
16 16
17 17 antenna_default = json.dumps({
18 18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 26 ]
27 27 ,
28 28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 36 })
37 37
38 38
39 39 tx_default = json.dumps({
40 40 "up": [[1,1,1,1,0,0,0,0],
41 41 [1,1,1,1,0,0,0,0],
42 42 [1,1,1,1,0,0,0,0],
43 43 [1,1,1,1,0,0,0,0],
44 44 [0,0,0,0,1,1,1,1],
45 45 [0,0,0,0,1,1,1,1],
46 46 [0,0,0,0,1,1,1,1],
47 47 [0,0,0,0,1,1,1,1]],
48 48
49 49 "down": [[1,1,1,1,0,0,0,0],
50 50 [1,1,1,1,0,0,0,0],
51 51 [1,1,1,1,0,0,0,0],
52 52 [1,1,1,1,0,0,0,0],
53 53 [0,0,0,0,1,1,1,1],
54 54 [0,0,0,0,1,1,1,1],
55 55 [0,0,0,0,1,1,1,1],
56 56 [0,0,0,0,1,1,1,1]],
57 57 })
58 58
59 59 rx_default = json.dumps({
60 60 "up": [[1,1,1,1,0,0,0,0],
61 61 [1,1,1,1,0,0,0,0],
62 62 [1,1,1,1,0,0,0,0],
63 63 [1,1,1,1,0,0,0,0],
64 64 [0,0,0,0,1,1,1,1],
65 65 [0,0,0,0,1,1,1,1],
66 66 [0,0,0,0,1,1,1,1],
67 67 [0,0,0,0,1,1,1,1]],
68 68
69 69 "down": [[1,1,1,1,0,0,0,0],
70 70 [1,1,1,1,0,0,0,0],
71 71 [1,1,1,1,0,0,0,0],
72 72 [1,1,1,1,0,0,0,0],
73 73 [0,0,0,0,1,1,1,1],
74 74 [0,0,0,0,1,1,1,1],
75 75 [0,0,0,0,1,1,1,1],
76 76 [0,0,0,0,1,1,1,1]],
77 77 })
78 78
79 79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 80 default_messages = {}
81 81
82 82 for i in range(1,65):
83 83 default_messages[str(i)] = "Module "+str(i)
84 84
85 85
86 86 ues_default = json.dumps({
87 87 "up": [0.533333,0.00000,1.06667,0.00000],
88 88 "down": [0.533333,0.00000,1.06667,0.00000]
89 89 })
90 90
91 91 onlyrx_default = json.dumps({
92 92 "up": False,
93 93 "down": False
94 94 })
95 95
96 96 def up_convertion(cadena):
97 97 valores = []
98 98 for c in cadena:
99 99 if c == 1.0: valores=valores+['000']
100 100 if c == 2.0: valores=valores+['001']
101 101 if c == 3.0: valores=valores+['010']
102 102 if c == 0.0: valores=valores+['011']
103 103 if c == 0.5: valores=valores+['100']
104 104 if c == 1.5: valores=valores+['101']
105 105 if c == 2.5: valores=valores+['110']
106 106 if c == 3.5: valores=valores+['111']
107 107
108 108 return valores
109 109
110 110 def up_conv_bits(value):
111 111
112 112 if value == 1.0: bits="000"
113 113 if value == 2.0: bits="001"
114 114 if value == 3.0: bits="010"
115 115 if value == 0.0: bits="011"
116 116 if value == 0.5: bits="100"
117 117 if value == 1.5: bits="101"
118 118 if value == 2.5: bits="110"
119 119 if value == 3.5: bits="111"
120 120
121 121 return bits
122 122
123 123 def down_convertion(cadena):
124 124 valores = []
125 125 for c in cadena:
126 126 if c == 1.0: valores=valores+['000']
127 127 if c == 2.0: valores=valores+['001']
128 128 if c == 3.0: valores=valores+['010']
129 129 if c == 0.0: valores=valores+['011']
130 130 if c == 0.5: valores=valores+['100']
131 131 if c == 1.5: valores=valores+['101']
132 132 if c == 2.5: valores=valores+['110']
133 133 if c == 3.5: valores=valores+['111']
134 134
135 135 return valores
136 136
137 137 def down_conv_bits(value):
138 138
139 139 if value == 1.0: bits="000"
140 140 if value == 2.0: bits="001"
141 141 if value == 3.0: bits="010"
142 142 if value == 0.0: bits="011"
143 143 if value == 0.5: bits="100"
144 144 if value == 1.5: bits="101"
145 145 if value == 2.5: bits="110"
146 146 if value == 3.5: bits="111"
147 147
148 148 return bits
149 149
150 150 def up_conv_value(bits):
151 151
152 152 if bits == "000": value=1.0
153 153 if bits == "001": value=2.0
154 154 if bits == "010": value=3.0
155 155 if bits == "011": value=0.0
156 156 if bits == "100": value=0.5
157 157 if bits == "101": value=1.5
158 158 if bits == "110": value=2.5
159 159 if bits == "111": value=3.5
160 160
161 161 return value
162 162
163 163 def down_conv_value(bits):
164 164
165 165 if bits == "000": value=1.0
166 166 if bits == "001": value=2.0
167 167 if bits == "010": value=3.0
168 168 if bits == "011": value=0.0
169 169 if bits == "100": value=0.5
170 170 if bits == "101": value=1.5
171 171 if bits == "110": value=2.5
172 172 if bits == "111": value=3.5
173 173
174 174 return value
175 175
176 176 def ip2position(module_number):
177 177 j=0
178 178 i=0
179 179 for x in range(0,module_number-1):
180 180 j=j+1
181 181 if j==8:
182 182 i=i+1
183 183 j=0
184 184
185 185 pos = [i,j]
186 186 return pos
187 187
188 188
189 189 def fromBinary2Char(binary_string):
190 190 number = int(binary_string, 2)
191 191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 192 number = number + 33
193 193 char = chr(number)
194 194 return char
195 195
196 196 def fromChar2Binary(char):
197 197 number = ord(char) - 33
198 198 #Minus 33 to get the real value
199 199 bits = bin(number)[2:]
200 200 #To ensure we have a string with 6bits
201 201 if len(bits) < 6:
202 202 bits = bits.zfill(6)
203 203 return bits
204 204
205 205 OPERATION_MODES = (
206 206 (0, 'Manual'),
207 207 (1, 'Automatic'),
208 208 )
209 209
210 210
211 211 class ABSConfiguration(Configuration):
212 212 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
213 213 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=json.dumps(status_default))
214 214 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
215 215 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
216 216 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
217 217
218 218 class Meta:
219 219 db_table = 'abs_configurations'
220 220
221 221 def get_absolute_url_plot(self):
222 222 return reverse('url_plot_abs_patterns', args=[str(self.id)])
223 223
224 224
225 225 def parms_to_dict(self):
226 226
227 227 parameters = {}
228 228
229 229 parameters['device_id'] = self.device.id
230 parameters['name'] = self.name
230 parameters['label'] = self.label
231 231 parameters['device_type'] = self.device.device_type.name
232 232 parameters['beams'] = {}
233 233
234 234 beams = ABSBeam.objects.filter(abs_conf=self)
235 235 b=1
236 236 for beam in beams:
237 237 #absbeam = ABSBeam.objects.get(pk=beams[beam])
238 238 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
239 239 b+=1
240 240
241 241 return parameters
242 242
243 243
244 244 def dict_to_parms(self, parameters):
245 245
246 self.name = parameters['name']
246 self.label = parameters['label']
247 247
248 248 absbeams = ABSBeam.objects.filter(abs_conf=self)
249 249 beams = parameters['beams']
250 250
251 251 if absbeams:
252 252 beams_number = len(beams)
253 253 absbeams_number = len(absbeams)
254 254 if beams_number==absbeams_number:
255 255 i = 1
256 256 for absbeam in absbeams:
257 257 absbeam.dict_to_parms(beams['beam'+str(i)])
258 258 i = i+1
259 259 elif beams_number > absbeams_number:
260 260 i = 1
261 261 for absbeam in absbeams:
262 262 absbeam.dict_to_parms(beams['beam'+str(i)])
263 263 i=i+1
264 264 for x in range(i,beams_number+1):
265 265 new_beam = ABSBeam(
266 266 name =beams['beam'+str(i)]['name'],
267 267 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
268 268 abs_conf = self,
269 269 tx =json.dumps(beams['beam'+str(i)]['tx']),
270 270 rx =json.dumps(beams['beam'+str(i)]['rx']),
271 271 ues =json.dumps(beams['beam'+str(i)]['ues']),
272 272 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
273 273 )
274 274 new_beam.save()
275 275 i=i+1
276 276 else: #beams_number < absbeams_number:
277 277 i = 1
278 278 for absbeam in absbeams:
279 279 if i <= beams_number:
280 280 absbeam.dict_to_parms(beams['beam'+str(i)])
281 281 i=i+1
282 282 else:
283 283 absbeam.delete()
284 284 else:
285 285 for beam in beams:
286 286 new_beam = ABSBeam(
287 287 name =beams[beam]['name'],
288 288 antenna =json.dumps(beams[beam]['antenna']),
289 289 abs_conf = self,
290 290 tx =json.dumps(beams[beam]['tx']),
291 291 rx =json.dumps(beams[beam]['rx']),
292 292 ues =json.dumps(beams[beam]['ues']),
293 293 only_rx =json.dumps(beams[beam]['only_rx'])
294 294 )
295 295 new_beam.save()
296 296
297 297
298 298
299 299 def update_from_file(self, parameters):
300 300
301 301 self.dict_to_parms(parameters)
302 302 self.save()
303 303
304 304
305 305 def get_beams(self, **kwargs):
306 306 '''
307 307 This function returns ABS Configuration beams
308 308 '''
309 309 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
310 310
311 311 def clone(self, **kwargs):
312 312
313 313 beams = self.get_beams()
314 314 self.pk = None
315 315 self.id = None
316 316 for attr, value in kwargs.items():
317 317 setattr(self, attr, value)
318 318 self.save()
319 319
320 320 for beam in beams:
321 321 beam.clone(abs_conf=self)
322 322
323 323 #-----For Active Beam-----
324 324 new_beams = ABSBeam.objects.filter(abs_conf=self)
325 325 self.active_beam = new_beams[0].id
326 326 self.save()
327 327 #-----For Active Beam-----
328 328 #-----For Device Status---
329 329 self.device.status = 3
330 330 self.device.save()
331 331 #-----For Device Status---
332 332
333 333 return self
334 334
335 335
336 336 def start_device(self):
337 337
338 338 if self.device.status == 3:
339 339
340 340 try:
341 341 #self.write_device()
342 342 send_task('task_change_beam', [self.id],)
343 343 self.message = 'ABS running'
344 344
345 345 except Exception as e:
346 346 self.message = str(e)
347 347 return False
348 348
349 349 return True
350 350
351 351 else:
352 352 self.message = 'Please, select Write ABS Device first.'
353 353 return False
354 354
355 355
356 356 def stop_device(self):
357 357
358 358 self.device.status = 2
359 359 self.device.save()
360 360 self.message = 'ABS has been stopped.'
361 361 self.save()
362 362
363 363 return True
364 364
365 365
366 366 def write_device(self):
367 367
368 368 """
369 369 This function sends the beams list to every abs module.
370 370 It needs 'module_conf' function
371 371 """
372 372
373 373 beams = ABSBeam.objects.filter(abs_conf=self)
374 374 nbeams = len(beams)
375 375 if self.connected_modules() == 0 :
376 376 self.message = "No ABS Module detected."
377 377 return False
378 378
379 379 #-------------Write each abs module-----------
380 380 if beams:
381 381 message = 'SNDF{:02d}'.format(nbeams)
382 382 for i, status in enumerate(self.module_status):
383 383 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
384 384 status = ['0'] * 64
385 385 n = 0
386 386
387 387 sock = self.send_multicast(message)
388 388
389 389 for i in range(64):
390 390 try:
391 391 data, address = sock.recvfrom(1024)
392 392 if data == '1':
393 393 status[int(address[0][10:])-1] = '3'
394 394 elif data == '0':
395 395 status[int(address[0][10:])-1] = '1'
396 396 except:
397 397 n += 1
398 398 sock.close()
399 399 else:
400 400 self.message = "ABS Configuration does not have beams"
401 401 return False
402 402
403 403 if n == 64:
404 404 self.message = "Could not write ABS Modules"
405 405 self.device.status = 0
406 406 self.module_status = ''.join(status)
407 407 self.save()
408 408 return False
409 409 else:
410 410 self.message = "ABS Beams List have been sent to ABS Modules"
411 411 self.active_beam = beams[0].pk
412 412
413 413 self.device.status = 3
414 414 self.module_status = ''.join(status)
415 415 self.save()
416 416 return True
417 417
418 418
419 419 def read_module(self, module):
420 420
421 421 """
422 422 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 423 """
424 424
425 425 ip_address = self.device.ip_address
426 426 ip_address = ip_address.split('.')
427 427 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 428 dot = '.'
429 429 module_ip = dot.join(module_seq)+'.'+str(module)
430 430 module_port = self.device.port_address
431 431 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 432
433 433 module_status = json.loads(self.module_status)
434 434 print(read_route)
435 435
436 436 module_bits = ''
437 437
438 438 try:
439 439 r_read = requests.get(read_route, timeout=0.5)
440 440 answer = r_read.json()
441 441 module_bits = answer['allbits']
442 442 except:
443 443 return {}
444 444
445 445 return module_bits
446 446
447 447 def read_device(self):
448 448
449 449 parms = {}
450 450 # Reads active modules.
451 451 module_status = json.loads(self.module_status)
452 452 total = 0
453 453 for status in module_status:
454 454 if module_status[status] != 0:
455 455 module_bits = self.read_module(int(status))
456 456 bits={}
457 457 if module_bits:
458 458 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 459 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 460 parms[str(status)] = bits
461 461
462 462 total +=1
463 463
464 464 if total==0:
465 465 self.message = "No ABS Module detected. Please select 'Status'."
466 466 return False
467 467
468 468
469 469
470 470 self.message = "ABS Modules have been read"
471 471 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 472 return parms
473 473
474 474
475 475 def connected_modules(self):
476 476 """
477 477 This function returns the number of connected abs-modules without updating.
478 478 """
479 479 num = 0
480 480 print(self.module_status)
481 481 for i, status in enumerate(self.module_status):
482 482 if status != '0':
483 483 num += 1
484 484 print('status {}:{}'.format(i+1, status))
485 485 return num
486 486
487 487 def send_multicast(self, message):
488 488
489 489 multicast_group = ('224.3.29.71', 10000)
490 490 # Create the datagram socket
491 491 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 492 sock.settimeout(0.01)
493 493 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
494 494 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 495 sent = sock.sendto(message, multicast_group)
496 496 print('Sending ' + message)
497 497 return sock
498 498
499 499 def status_device(self):
500 500 """
501 501 This function returns the status of all abs-modules as one.
502 502 If at least one module is connected, its answer is "1"
503 503 """
504 504
505 505 sock = self.send_multicast('MNTR')
506 506
507 507 n = 0
508 508 status = ['0'] * 64
509 509 for i in range(64):
510 510 try:
511 511 data, address = sock.recvfrom(1024)
512 512 if data == '1':
513 513 status[int(address[0][10:])-1] = '3'
514 514 elif data == '0':
515 515 status[int(address[0][10:])-1] = '1'
516 516 n += 1
517 517 print('Module: {} connected'.format(address))
518 518 except:
519 519 pass
520 520 sock.close()
521 521
522 522 if n > 0:
523 523 self.message = 'ABS modules Status have been updated.'
524 524 self.device.status = 1
525 525 else:
526 526 self.device.status = 0
527 527 self.message = 'No ABS module is connected.'
528 528 self.module_status = ''.join(status)
529 529 self.save()
530 530
531 531 return self.device.status
532 532
533 533
534 534 def send_beam(self, beam_pos):
535 535 """
536 536 This function connects to a multicast group and sends the beam number
537 537 to all abs modules.
538 538 """
539 539
540 540 # Se manda a cero RC para poder realizar cambio de beam
541 541 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
542 542 confdds = ''
543 543 confjars = ''
544 544 confrc = ''
545 545
546 546 #TO STOP DEVICES: DDS-JARS-RC
547 547 for i in range(0,len(confs)):
548 548 if i==0:
549 549 for conf in confs:
550 550 if conf.device.device_type.name == 'dds':
551 551 confdds = conf
552 552 confdds.stop_device()
553 553 break
554 554 if i==1:
555 555 for conf in confs:
556 556 if conf.device.device_type.name == 'jars':
557 557 confjars = conf
558 558 confjars.stop_device()
559 559 break
560 560 if i==2:
561 561 for conf in confs:
562 562 if conf.device.device_type.name == 'rc':
563 563 confrc = conf
564 564 confrc.stop_device()
565 565 break
566 566
567 567 if beam_pos > 0:
568 568 beam_pos = beam_pos - 1
569 569 else:
570 570 beam_pos = 0
571 571
572 572 #El indice del apunte debe ser menor que el numero total de apuntes
573 573 #El servidor tcp en el embebido comienza a contar desde 0
574 574 status = ['0'] * 64
575 575 message = 'CHGB{}'.format(beam_pos)
576 576 sock = self.send_multicast(message)
577 577
578 578 for i in range(64):
579 579 try:
580 580 data, address = sock.recvfrom(1024)
581 581 print address, data
582 582 if data == '1':
583 583 status[int(address[0][10:])-1] = '3'
584 584 elif data == '0':
585 585 status[int(address[0][10:])-1] = '1'
586 586 except:
587 587 pass
588 588
589 589 sock.close()
590 590
591 591 #Start DDS-RC-JARS
592 592 if confdds:
593 593 confdds.start_device()
594 594 if confrc:
595 595 #print confrc
596 596 confrc.start_device()
597 597 if confjars:
598 598 confjars.start_device()
599 599
600 600 self.message = "ABS Beam has been changed"
601 601 self.module_status = ''.join(status)
602 602 self.save()
603 603 return True
604 604
605 605
606 606 def get_absolute_url_import(self):
607 607 return reverse('url_import_abs_conf', args=[str(self.id)])
608 608
609 609
610 610 class ABSBeam(models.Model):
611 611
612 612 name = models.CharField(max_length=60, default='Beam')
613 613 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
614 614 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
615 615 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
616 616 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
617 617 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
618 618 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
619 619 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
620 620 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
621 621
622 622 class Meta:
623 623 db_table = 'abs_beams'
624 624
625 625 def __unicode__(self):
626 626 return u'%s' % (self.name)
627 627
628 628 def parms_to_dict(self):
629 629
630 630 parameters = {}
631 631 parameters['name'] = self.name
632 632 parameters['antenna'] = ast.literal_eval(self.antenna)
633 633 parameters['abs_conf'] = self.abs_conf.name
634 634 parameters['tx'] = ast.literal_eval(self.tx)
635 635 parameters['rx'] = ast.literal_eval(self.rx)
636 636 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
637 637 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
638 638 parameters['ues'] = ast.literal_eval(self.ues)
639 639 parameters['only_rx'] = json.loads(self.only_rx)
640 640
641 641 return parameters
642 642
643 643 def dict_to_parms(self, parameters):
644 644
645 645 self.name = parameters['name']
646 646 self.antenna = json.dumps(parameters['antenna'])
647 647 #self.abs_conf = parameters['abs_conf']
648 648 self.tx = json.dumps(parameters['tx'])
649 649 self.rx = json.dumps(parameters['rx'])
650 650 #self.s_time = parameters['s_time']
651 651 #self.e_time = parameters['e_time']
652 652 self.ues = json.dumps(parameters['ues'])
653 653 self.only_rx = json.dumps(parameters['only_rx'])
654 654 self.save()
655 655
656 656
657 657 def clone(self, **kwargs):
658 658
659 659 self.pk = None
660 660 self.id = None
661 661 for attr, value in kwargs.items():
662 662 setattr(self, attr, value)
663 663
664 664 self.save()
665 665
666 666 return self
667 667
668 668
669 669 def module_6bits(self, module):
670 670 """
671 671 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
672 672 """
673 673 if module > 64:
674 674 beam_bits = ""
675 675 return beam_bits
676 676
677 677 data = ast.literal_eval(self.antenna)
678 678 up_data = data['antenna_up']
679 679 down_data = data['antenna_down']
680 680
681 681 pos = ip2position(module)
682 682 up_value = up_data[pos[0]][pos[1]]
683 683 down_value = down_data[pos[0]][pos[1]]
684 684
685 685 up_bits = up_conv_bits(up_value)
686 686 down_bits = down_conv_bits(down_value)
687 687 beam_bits = up_bits+down_bits
688 688
689 689 return beam_bits
690 690
691 691
692 692 @property
693 693 def get_upvalues(self):
694 694 """
695 695 This function reads antenna pattern and show the up-value of one abs module
696 696 """
697 697
698 698 data = ast.literal_eval(self.antenna)
699 699 up_data = data['antenna_up']
700 700
701 701 up_values = []
702 702 for data in up_data:
703 703 for i in range(0,8):
704 704 up_values.append(data[i])
705 705
706 706 return up_values
707 707
708 708 @property
709 709 def antenna_upvalues(self):
710 710 """
711 711 This function reads antenna pattern and show the up - values of one abs beam
712 712 in a particular order
713 713 """
714 714 data = ast.literal_eval(self.antenna)
715 715 up_data = data['antenna_up']
716 716
717 717 return up_data
718 718
719 719 @property
720 720 def antenna_downvalues(self):
721 721 """
722 722 This function reads antenna pattern and show the down - values of one abs beam
723 723 in a particular order
724 724 """
725 725 data = ast.literal_eval(self.antenna)
726 726 down_data = data['antenna_down']
727 727
728 728 return down_data
729 729
730 730 @property
731 731 def get_downvalues(self):
732 732 """
733 733 This function reads antenna pattern and show the down-value of one abs module
734 734 """
735 735
736 736 data = ast.literal_eval(self.antenna)
737 737 down_data = data['antenna_down']
738 738
739 739 down_values = []
740 740 for data in down_data:
741 741 for i in range(0,8):
742 742 down_values.append(data[i])
743 743
744 744 return down_values
745 745
746 746 @property
747 747 def get_up_ues(self):
748 748 """
749 749 This function shows the up-ues-value of one beam
750 750 """
751 751 data = ast.literal_eval(self.ues)
752 752 up_ues = data['up']
753 753
754 754 return up_ues
755 755
756 756 @property
757 757 def get_down_ues(self):
758 758 """
759 759 This function shows the down-ues-value of one beam
760 760 """
761 761 data = ast.literal_eval(self.ues)
762 762 down_ues = data['down']
763 763
764 764 return down_ues
765 765
766 766 @property
767 767 def get_up_onlyrx(self):
768 768 """
769 769 This function shows the up-onlyrx-value of one beam
770 770 """
771 771 data = json.loads(self.only_rx)
772 772 up_onlyrx = data['up']
773 773
774 774 return up_onlyrx
775 775
776 776 @property
777 777 def get_down_onlyrx(self):
778 778 """
779 779 This function shows the down-onlyrx-value of one beam
780 780 """
781 781 data = json.loads(self.only_rx)
782 782 down_onlyrx = data['down']
783 783
784 784 return down_onlyrx
785 785
786 786 @property
787 787 def get_tx(self):
788 788 """
789 789 This function shows the tx-values of one beam
790 790 """
791 791 data = json.loads(self.tx)
792 792
793 793 return data
794 794
795 795 @property
796 796 def get_uptx(self):
797 797 """
798 798 This function shows the up-tx-values of one beam
799 799 """
800 800 data = json.loads(self.tx)
801 801 up_data = data['up']
802 802
803 803 up_values = []
804 804 for data in up_data:
805 805 for i in range(0,8):
806 806 up_values.append(data[i])
807 807
808 808 return up_values
809 809
810 810 @property
811 811 def get_downtx(self):
812 812 """
813 813 This function shows the down-tx-values of one beam
814 814 """
815 815 data = json.loads(self.tx)
816 816 down_data = data['down']
817 817
818 818 down_values = []
819 819 for data in down_data:
820 820 for i in range(0,8):
821 821 down_values.append(data[i])
822 822
823 823 return down_values
824 824
825 825
826 826
827 827 @property
828 828 def get_rx(self):
829 829 """
830 830 This function shows the rx-values of one beam
831 831 """
832 832 data = json.loads(self.rx)
833 833
834 834 return data
835 835
836 836 @property
837 837 def get_uprx(self):
838 838 """
839 839 This function shows the up-rx-values of one beam
840 840 """
841 841 data = json.loads(self.rx)
842 842 up_data = data['up']
843 843
844 844 up_values = []
845 845 for data in up_data:
846 846 for i in range(0,8):
847 847 up_values.append(data[i])
848 848
849 849 return up_values
850 850
851 851 @property
852 852 def get_downrx(self):
853 853 """
854 854 This function shows the down-rx-values of one beam
855 855 """
856 856 data = json.loads(self.rx)
857 857 down_data = data['down']
858 858
859 859 down_values = []
860 860 for data in down_data:
861 861 for i in range(0,8):
862 862 down_values.append(data[i])
863 863
864 864 return down_values
@@ -1,476 +1,342
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
2 2 {% block extra-head %}
3 3 <style>
4 4 .abs {
5 border: 2px solid #00334d;
6 vertical-align: center;
5 width: auto;
7 6 display: inline-block;
8 }
9
10 .abs tr:nth-child(1) {
11 border-bottom: 1px dashed #00334d;
12 }
13
14 .abs tr {
15 border-bottom: 0px solid #00334d;
7 text-align: center;
16 8 }
17 9
18 10 .abs td {
19 border-right: 1px dashed #00334d;
20 text-align: center;
21 padding: 5px;
11 padding: 4px;
22 12 }
23 13
14 .module td {
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
17 border: 1px solid
18 }
24 19
25 20 .legend {
26 21 margin-left: 15px;
27 22 display: inline-block;
28 border: 2px solid #00334d;
23 border: 2px solid;
29 24 vertical-align: top;
30 25 }
31 26
32 27 .legend th {
33 border-bottom: 1px dashed #00334d;
28 border-bottom: 1px dashed;
34 29 font-weight: bold;
35 30 vertical-align: center;
36 31 text-align: center;
37 32 }
38 33
39 34 .legend td {
40 35 padding: 2px;
41 36 text-align: center;
42 37 }
43 38
44
45 .north {
46 border: 2px solid #00334d;
47 vertical-align: center;
48 font-weight: bold;
49 }
50
51 .north tr {
52 border: 1px solid #ffffff;
53
54 }
55
56 .north td {
57 border: 2px solid #e2e2e7;
58 text-align: center;
59 padding: 1px 15px 1px 15px;
60 }
61
62 .north tr:nth-child(even) td:nth-child(n) {
63 border-bottom: 12px solid #e2e2e7;
64 }
65
66 .north td:nth-child(n) {
67 border-right: 12px solid #e2e2e7;
68 }
69
70 .north td:nth-last-child(4n+1) {
71 border-right: 2px solid #e2e2e7;
72 }
73
74 .north tr:nth-last-child(1) td:nth-child(n) {
75 border-bottom: 3px solid #e2e2e7;
76 }
77
78 .east {
79 border: 2px solid #00334d;
80 vertical-align: center;
81 font-weight: bold;
82 }
83
84 .east tr {
85 border: 1px solid #ffffff;
86 }
87
88 .east td {
89 border: 2px solid #e2e2e7;
90 text-align: center;
91 padding: 1px 15px 1px 15px;
92 }
93
94 .east tr:nth-child(even) td:nth-child(n) {
95 border-bottom: 12px solid #e2e2e7;
96 }
97
98 .east td:nth-child(n) {
99 border-right: 12px solid #e2e2e7;
100 }
101
102 .east td:nth-last-child(4n+1) {
103 border-right: 2px solid #e2e2e7;
104 }
105
106 .east tr:nth-last-child(1) td:nth-child(n) {
107 border-bottom: 3px solid #e2e2e7;
108 }
109
110 .west {
111 border: 2px solid #00334d;
112 vertical-align: center;
113 font-weight: bold;
114 }
115
116 .west tr {
117 border: 1px solid #ffffff;
118 }
119
120 .west td {
121 border: 2px solid #e2e2e7;
122 text-align: center;
123 padding: 1px 15px 1px 15px;
124 }
125
126 .west tr:nth-child(even) td:nth-child(n) {
127 border-bottom: 12px solid #e2e2e7;
128 }
129
130 .west td:nth-child(n) {
131 border-right: 12px solid #e2e2e7;
132 }
133
134 .west td:nth-last-child(4n+1) {
135 border-right: 2px solid #e2e2e7;
136 }
137
138 .west tr:nth-last-child(1) td:nth-child(n) {
139 border-bottom: 3px solid #e2e2e7;
140 }
141
142 .south {
143 border: 2px solid #00334d;
144 vertical-align: center;
145 font-weight: bold;
146 }
147
148 .south tr {
149 border: 1px solid #ffffff;
150 }
151
152 .south td {
153 border: 2px solid #e2e2e7;
154 text-align: center;
155 padding: 1px 15px 1px 15px;
156 }
157
158 .south tr:nth-child(even) td:nth-child(n) {
159 border-bottom: 12px solid #e2e2e7;
160 }
161
162 .south td:nth-child(n) {
163 border-right: 12px solid #e2e2e7;
164 }
165
166 .south td:nth-last-child(4n+1) {
167 border-right: 2px solid #e2e2e7;
168 }
169
170 .south tr:nth-last-child(1) td:nth-child(n) {
171 border-bottom: 3px solid #e2e2e7;
172 }
173 39 </style>
174 40 {% endblock %}
175 41 {% block extra-menu-actions %}
176 42 <li>
177 43 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
178 44 <span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Patterns </a>
179 45 </li>
180 {% endblock %}
46 {% endblock %}
181 47 {% block extra-content %}
182 48 {% if beams %}
183 49 <h4>Beams:</h4>
184 50 <div class="container">
185 51 <ul class="nav nav-pills">
186 52 {% for beam in beams %}
187 53 <li {%if beam.pk == active_beam %} class="active" {% endif %}>
188 54 <a data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
189 55 </li>
190 56 {% endfor %}
191 57 </ul>
192 58
193 59 <div class="tab-content">
194 60 {% for beam in beams %}
195 61 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}active in{% endif %}">
196 62 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
197 63 <table id="abs_pattern{{forloop.counter}}" class="abs">
198 64 <tr>
199 65 <td>
200 66 <b>North Quarter</b>
201 <table class="north ">
67 <table class="module">
202 68 <tr>
203 69 <td {%if beam.pk == active_beam %} {{color_status.1}} t{%endif%} itle='{{module_messages.1}}'>{{beam.get_upvalues.0}}</td>
204 70 <td {%if beam.pk == active_beam %} {{color_status.2}} t{%endif%} itle='{{module_messages.2}}'>{{beam.get_upvalues.1}}</td>
205 71 <td {%if beam.pk == active_beam %} {{color_status.3}} t{%endif%} itle='{{module_messages.3}}'>{{beam.get_upvalues.2}}</td>
206 72 <td {%if beam.pk == active_beam %} {{color_status.4}} t{%endif%} itle='{{module_messages.4}}'>{{beam.get_upvalues.3}}</td>
207 73 </tr>
208 74 <tr>
209 75 <td {%if beam.pk == active_beam %} {{color_status.1}} t{%endif%} itle='{{module_messages.1}}'>{{beam.get_downvalues.0}}</td>
210 76 <td {%if beam.pk == active_beam %} {{color_status.2}} t{%endif%} itle='{{module_messages.2}}'>{{beam.get_downvalues.1}}</td>
211 77 <td {%if beam.pk == active_beam %} {{color_status.3}} t{%endif%} itle='{{module_messages.3}}'>{{beam.get_downvalues.2}}</td>
212 78 <td {%if beam.pk == active_beam %} {{color_status.4}} t{%endif%} itle='{{module_messages.4}}'>{{beam.get_downvalues.3}}</td>
213 79 </tr>
214 80 <tr>
215 81 <td {%if beam.pk == active_beam %} {{color_status.9}} t{%endif%} itle='{{module_messages.9}}'>{{beam.get_upvalues.8}}</td>
216 82 <td {%if beam.pk == active_beam %} {{color_status.10}} {%endif%} title='{{module_messages.10}}'>{{beam.get_upvalues.9}}</td>
217 83 <td {%if beam.pk == active_beam %} {{color_status.11}} {%endif%} title='{{module_messages.11}}'>{{beam.get_upvalues.10}}</td>
218 84 <td {%if beam.pk == active_beam %} {{color_status.12}} {%endif%} title='{{module_messages.12}}'>{{beam.get_upvalues.11}}</td>
219 85 </tr>
220 86 <tr>
221 87 <td {%if beam.pk == active_beam %} {{color_status.9}} t{%endif%} itle='{{module_messages.9}}'>{{beam.get_downvalues.8}}</td>
222 88 <td {%if beam.pk == active_beam %} {{color_status.10}} {%endif%} title='{{module_messages.10}}'>{{beam.get_downvalues.9}}</td>
223 89 <td {%if beam.pk == active_beam %} {{color_status.11}} {%endif%} title='{{module_messages.11}}'>{{beam.get_downvalues.10}}</td>
224 90 <td {%if beam.pk == active_beam %} {{color_status.12}} {%endif%} title='{{module_messages.12}}'>{{beam.get_downvalues.11}}</td>
225 91 </tr>
226 92 <tr>
227 93 <td {%if beam.pk == active_beam %} {{color_status.17}} {%endif%} title='{{module_messages.17}}'>{{beam.get_upvalues.16}}</td>
228 94 <td {%if beam.pk == active_beam %} {{color_status.18}} {%endif%} title='{{module_messages.18}}'>{{beam.get_upvalues.17}}</td>
229 95 <td {%if beam.pk == active_beam %} {{color_status.19}} {%endif%} title='{{module_messages.19}}'>{{beam.get_upvalues.18}}</td>
230 96 <td {%if beam.pk == active_beam %} {{color_status.20}} {%endif%} title='{{module_messages.20}}'>{{beam.get_upvalues.19}}</td>
231 97 </tr>
232 98 <tr>
233 99 <td {%if beam.pk == active_beam %} {{color_status.17}} {%endif%} title='{{module_messages.17}}'>{{beam.get_downvalues.16}}</td>
234 100 <td {%if beam.pk == active_beam %} {{color_status.18}} {%endif%} title='{{module_messages.18}}'>{{beam.get_downvalues.17}}</td>
235 101 <td {%if beam.pk == active_beam %} {{color_status.19}} {%endif%} title='{{module_messages.19}}'>{{beam.get_downvalues.18}}</td>
236 102 <td {%if beam.pk == active_beam %} {{color_status.20}} {%endif%} title='{{module_messages.20}}'>{{beam.get_downvalues.19}}</td>
237 103 </tr>
238 104 <tr>
239 105 <td {%if beam.pk == active_beam %} {{color_status.25}} {%endif%} title='{{module_messages.25}}'>{{beam.get_upvalues.24}}</td>
240 106 <td {%if beam.pk == active_beam %} {{color_status.26}} {%endif%} title='{{module_messages.26}}'>{{beam.get_upvalues.25}}</td>
241 107 <td {%if beam.pk == active_beam %} {{color_status.27}} {%endif%} title='{{module_messages.27}}'>{{beam.get_upvalues.26}}</td>
242 108 <td {%if beam.pk == active_beam %} {{color_status.28}} {%endif%} title='{{module_messages.28}}'>{{beam.get_upvalues.27}}</td>
243 109 </tr>
244 110 <tr>
245 111 <td {%if beam.pk == active_beam %} {{color_status.25}} {%endif%} title='{{module_messages.25}}'>{{beam.get_downvalues.24}}</td>
246 112 <td {%if beam.pk == active_beam %} {{color_status.26}} {%endif%} title='{{module_messages.26}}'>{{beam.get_downvalues.25}}</td>
247 113 <td {%if beam.pk == active_beam %} {{color_status.27}} {%endif%} title='{{module_messages.27}}'>{{beam.get_downvalues.26}}</td>
248 114 <td {%if beam.pk == active_beam %} {{color_status.28}} {%endif%} title='{{module_messages.28}}'>{{beam.get_downvalues.27}}</td>
249 115 </tr>
250 116 </table>
251 117 </td>
252 118 <td>
253 119 <b>East Quarter</b>
254 <table class="east ">
120 <table class="module">
255 121 <tr>
256 122 <td {%if beam.pk == active_beam %} {{color_status.5}} t{%endif%} itle='{{module_messages.5}}'>{{beam.get_upvalues.4}}</td>
257 123 <td {%if beam.pk == active_beam %} {{color_status.6}} t{%endif%} itle='{{module_messages.6}}'>{{beam.get_upvalues.5}}</td>
258 124 <td {%if beam.pk == active_beam %} {{color_status.7}} t{%endif%} itle='{{module_messages.7}}'>{{beam.get_upvalues.6}}</td>
259 125 <td {%if beam.pk == active_beam %} {{color_status.8}} t{%endif%} itle='{{module_messages.8}}'>{{beam.get_upvalues.7}}</td>
260 126 </tr>
261 127 <tr>
262 128 <td {%if beam.pk == active_beam %} {{color_status.5}} t{%endif%} itle='{{module_messages.5}}'>{{beam.get_downvalues.4}}</td>
263 129 <td {%if beam.pk == active_beam %} {{color_status.6}} t{%endif%} itle='{{module_messages.6}}'>{{beam.get_downvalues.5}}</td>
264 130 <td {%if beam.pk == active_beam %} {{color_status.7}} t{%endif%} itle='{{module_messages.7}}'>{{beam.get_downvalues.6}}</td>
265 131 <td {%if beam.pk == active_beam %} {{color_status.8}} t{%endif%} itle='{{module_messages.8}}'>{{beam.get_downvalues.7}}</td>
266 132 </tr>
267 133 <tr>
268 134 <td {%if beam.pk == active_beam %} {{color_status.13}} {%endif%} title='{{module_messages.13}}'>{{beam.get_upvalues.12}}</td>
269 135 <td {%if beam.pk == active_beam %} {{color_status.14}} {%endif%} title='{{module_messages.14}}'>{{beam.get_upvalues.13}}</td>
270 136 <td {%if beam.pk == active_beam %} {{color_status.15}} {%endif%} title='{{module_messages.15}}'>{{beam.get_upvalues.14}}</td>
271 137 <td {%if beam.pk == active_beam %} {{color_status.16}} {%endif%} title='{{module_messages.16}}'>{{beam.get_upvalues.15}}</td>
272 138 </tr>
273 139 <tr>
274 140 <td {%if beam.pk == active_beam %} {{color_status.13}} {%endif%} title='{{module_messages.13}}'>{{beam.get_downvalues.12}}</td>
275 141 <td {%if beam.pk == active_beam %} {{color_status.14}} {%endif%} title='{{module_messages.14}}'>{{beam.get_downvalues.13}}</td>
276 142 <td {%if beam.pk == active_beam %} {{color_status.15}} {%endif%} title='{{module_messages.15}}'>{{beam.get_downvalues.14}}</td>
277 143 <td {%if beam.pk == active_beam %} {{color_status.16}} {%endif%} title='{{module_messages.16}}'>{{beam.get_downvalues.15}}</td>
278 144 </tr>
279 145 <tr>
280 146 <td {%if beam.pk == active_beam %} {{color_status.21}} {%endif%} title='{{module_messages.21}}'>{{beam.get_upvalues.20}}</td>
281 147 <td {%if beam.pk == active_beam %} {{color_status.22}} {%endif%} title='{{module_messages.22}}'>{{beam.get_upvalues.21}}</td>
282 148 <td {%if beam.pk == active_beam %} {{color_status.23}} {%endif%} title='{{module_messages.23}}'>{{beam.get_upvalues.22}}</td>
283 149 <td {%if beam.pk == active_beam %} {{color_status.24}} {%endif%} title='{{module_messages.24}}'>{{beam.get_upvalues.23}}</td>
284 150 </tr>
285 151 <tr>
286 152 <td {%if beam.pk == active_beam %} {{color_status.21}} {%endif%} title='{{module_messages.21}}'>{{beam.get_downvalues.20}}</td>
287 153 <td {%if beam.pk == active_beam %} {{color_status.22}} {%endif%} title='{{module_messages.22}}'>{{beam.get_downvalues.21}}</td>
288 154 <td {%if beam.pk == active_beam %} {{color_status.23}} {%endif%} title='{{module_messages.23}}'>{{beam.get_downvalues.22}}</td>
289 155 <td {%if beam.pk == active_beam %} {{color_status.24}} {%endif%} title='{{module_messages.24}}'>{{beam.get_downvalues.23}}</td>
290 156 </tr>
291 157 <tr>
292 158 <td {%if beam.pk == active_beam %} {{color_status.29}} {%endif%} title='{{module_messages.29}}'>{{beam.get_upvalues.28}}</td>
293 159 <td {%if beam.pk == active_beam %} {{color_status.30}} {%endif%} title='{{module_messages.30}}'>{{beam.get_upvalues.29}}</td>
294 160 <td {%if beam.pk == active_beam %} {{color_status.31}} {%endif%} title='{{module_messages.31}}'>{{beam.get_upvalues.30}}</td>
295 161 <td {%if beam.pk == active_beam %} {{color_status.32}} {%endif%} title='{{module_messages.32}}'>{{beam.get_upvalues.31}}</td>
296 162 </tr>
297 163 <tr>
298 164 <td {%if beam.pk == active_beam %} {{color_status.29}} {%endif%} title='{{module_messages.29}}'>{{beam.get_downvalues.28}}</td>
299 165 <td {%if beam.pk == active_beam %} {{color_status.30}} {%endif%} title='{{module_messages.30}}'>{{beam.get_downvalues.29}}</td>
300 166 <td {%if beam.pk == active_beam %} {{color_status.31}} {%endif%} title='{{module_messages.31}}'>{{beam.get_downvalues.30}}</td>
301 167 <td {%if beam.pk == active_beam %} {{color_status.32}} {%endif%} title='{{module_messages.32}}'>{{beam.get_downvalues.31}}</td>
302 168 </tr>
303 169 </table>
304 170 </td>
305 171 </tr>
306 172 <tr>
307 173 <td>
308 174 <b>West Quarter</b>
309 <table class="west ">
175 <table class="module">
310 176 <tr>
311 177 <td {%if beam.pk == active_beam %} {{color_status.33}} {%endif%} title='{{module_messages.33}}'>{{beam.get_upvalues.32}}</td>
312 178 <td {%if beam.pk == active_beam %} {{color_status.34}} {%endif%} title='{{module_messages.34}}'>{{beam.get_upvalues.33}}</td>
313 179 <td {%if beam.pk == active_beam %} {{color_status.35}} {%endif%} title='{{module_messages.35}}'>{{beam.get_upvalues.34}}</td>
314 180 <td {%if beam.pk == active_beam %} {{color_status.36}} {%endif%} title='{{module_messages.36}}'>{{beam.get_upvalues.35}}</td>
315 181 </tr>
316 182 <tr>
317 183 <td {%if beam.pk == active_beam %} {{color_status.33}} {%endif%} title='{{module_messages.33}}'>{{beam.get_downvalues.32}}</td>
318 184 <td {%if beam.pk == active_beam %} {{color_status.34}} {%endif%} title='{{module_messages.34}}'>{{beam.get_downvalues.33}}</td>
319 185 <td {%if beam.pk == active_beam %} {{color_status.35}} {%endif%} title='{{module_messages.35}}'>{{beam.get_downvalues.34}}</td>
320 186 <td {%if beam.pk == active_beam %} {{color_status.36}} {%endif%} title='{{module_messages.36}}'>{{beam.get_downvalues.35}}</td>
321 187 </tr>
322 188 <tr>
323 189 <td {%if beam.pk == active_beam %} {{color_status.41}} {%endif%} title='{{module_messages.41}}'>{{beam.get_upvalues.40}}</td>
324 190 <td {%if beam.pk == active_beam %} {{color_status.42}} {%endif%} title='{{module_messages.42}}'>{{beam.get_upvalues.41}}</td>
325 191 <td {%if beam.pk == active_beam %} {{color_status.43}} {%endif%} title='{{module_messages.43}}'>{{beam.get_upvalues.42}}</td>
326 192 <td {%if beam.pk == active_beam %} {{color_status.44}} {%endif%} title='{{module_messages.44}}'>{{beam.get_upvalues.43}}</td>
327 193 </tr>
328 194 <tr>
329 195 <td {%if beam.pk == active_beam %} {{color_status.41}} {%endif%} title='{{module_messages.41}}'>{{beam.get_downvalues.40}}</td>
330 196 <td {%if beam.pk == active_beam %} {{color_status.42}} {%endif%} title='{{module_messages.42}}'>{{beam.get_downvalues.41}}</td>
331 197 <td {%if beam.pk == active_beam %} {{color_status.43}} {%endif%} title='{{module_messages.43}}'>{{beam.get_downvalues.42}}</td>
332 198 <td {%if beam.pk == active_beam %} {{color_status.44}} {%endif%} title='{{module_messages.44}}'>{{beam.get_downvalues.43}}</td>
333 199 </tr>
334 200 <tr>
335 201 <td {%if beam.pk == active_beam %} {{color_status.49}} {%endif%} title='{{module_messages.49}}'>{{beam.get_upvalues.48}}</td>
336 202 <td {%if beam.pk == active_beam %} {{color_status.50}} {%endif%} title='{{module_messages.50}}'>{{beam.get_upvalues.49}}</td>
337 203 <td {%if beam.pk == active_beam %} {{color_status.51}} {%endif%} title='{{module_messages.51}}'>{{beam.get_upvalues.50}}</td>
338 204 <td {%if beam.pk == active_beam %} {{color_status.52}} {%endif%} title='{{module_messages.52}}'>{{beam.get_upvalues.51}}</td>
339 205 </tr>
340 206 <tr>
341 207 <td {%if beam.pk == active_beam %} {{color_status.49}} {%endif%} title='{{module_messages.49}}'>{{beam.get_downvalues.48}}</td>
342 208 <td {%if beam.pk == active_beam %} {{color_status.50}} {%endif%} title='{{module_messages.50}}'>{{beam.get_downvalues.49}}</td>
343 209 <td {%if beam.pk == active_beam %} {{color_status.51}} {%endif%} title='{{module_messages.51}}'>{{beam.get_downvalues.50}}</td>
344 210 <td {%if beam.pk == active_beam %} {{color_status.52}} {%endif%} title='{{module_messages.52}}'>{{beam.get_downvalues.51}}</td>
345 211 </tr>
346 212 <tr>
347 213 <td {%if beam.pk == active_beam %} {{color_status.57}} {%endif%} title='{{module_messages.57}}'>{{beam.get_upvalues.56}}</td>
348 214 <td {%if beam.pk == active_beam %} {{color_status.58}} {%endif%} title='{{module_messages.58}}'>{{beam.get_upvalues.57}}</td>
349 215 <td {%if beam.pk == active_beam %} {{color_status.59}} {%endif%} title='{{module_messages.59}}'>{{beam.get_upvalues.58}}</td>
350 216 <td {%if beam.pk == active_beam %} {{color_status.60}} {%endif%} title='{{module_messages.60}}'>{{beam.get_upvalues.59}}</td>
351 217 </tr>
352 218 <tr>
353 219 <td {%if beam.pk == active_beam %} {{color_status.57}} {%endif%} title='{{module_messages.57}}'>{{beam.get_downvalues.56}}</td>
354 220 <td {%if beam.pk == active_beam %} {{color_status.58}} {%endif%} title='{{module_messages.58}}'>{{beam.get_downvalues.57}}</td>
355 221 <td {%if beam.pk == active_beam %} {{color_status.59}} {%endif%} title='{{module_messages.59}}'>{{beam.get_downvalues.58}}</td>
356 222 <td {%if beam.pk == active_beam %} {{color_status.60}} {%endif%} title='{{module_messages.60}}'>{{beam.get_downvalues.59}}</td>
357 223 </tr>
358 224 </table>
359 225 </td>
360 226 <td>
361 227 <b>South Quarter</b>
362 <table class="south ">
228 <table class="module">
363 229 <tr>
364 230 <td {%if beam.pk == active_beam %} {{color_status.37}} {%endif%} title='{{module_messages.37}}'>{{beam.get_upvalues.36}}</td>
365 231 <td {%if beam.pk == active_beam %} {{color_status.38}} {%endif%} title='{{module_messages.38}}'>{{beam.get_upvalues.37}}</td>
366 232 <td {%if beam.pk == active_beam %} {{color_status.39}} {%endif%} title='{{module_messages.39}}'>{{beam.get_upvalues.38}}</td>
367 233 <td {%if beam.pk == active_beam %} {{color_status.40}} {%endif%} title='{{module_messages.40}}'>{{beam.get_upvalues.39}}</td>
368 234 </tr>
369 235 <tr>
370 236 <td {%if beam.pk == active_beam %} {{color_status.37}} {%endif%} title='{{module_messages.37}}'>{{beam.get_downvalues.36}}</td>
371 237 <td {%if beam.pk == active_beam %} {{color_status.38}} {%endif%} title='{{module_messages.38}}'>{{beam.get_downvalues.37}}</td>
372 238 <td {%if beam.pk == active_beam %} {{color_status.39}} {%endif%} title='{{module_messages.39}}'>{{beam.get_downvalues.38}}</td>
373 239 <td {%if beam.pk == active_beam %} {{color_status.40}} {%endif%} title='{{module_messages.40}}'>{{beam.get_downvalues.39}}</td>
374 240 </tr>
375 241 <tr>
376 242 <td {%if beam.pk == active_beam %} {{color_status.45}} {%endif%} title='{{module_messages.45}}'>{{beam.get_upvalues.44}}</td>
377 243 <td {%if beam.pk == active_beam %} {{color_status.46}} {%endif%} title='{{module_messages.46}}'>{{beam.get_upvalues.45}}</td>
378 244 <td {%if beam.pk == active_beam %} {{color_status.47}} {%endif%} title='{{module_messages.47}}'>{{beam.get_upvalues.46}}</td>
379 245 <td {%if beam.pk == active_beam %} {{color_status.48}} {%endif%} title='{{module_messages.48}}'>{{beam.get_upvalues.47}}</td>
380 246 </tr>
381 247 <tr>
382 248 <td {%if beam.pk == active_beam %} {{color_status.45}} {%endif%} title='{{module_messages.45}}'>{{beam.get_downvalues.44}}</td>
383 249 <td {%if beam.pk == active_beam %} {{color_status.46}} {%endif%} title='{{module_messages.46}}'>{{beam.get_downvalues.45}}</td>
384 250 <td {%if beam.pk == active_beam %} {{color_status.47}} {%endif%} title='{{module_messages.47}}'>{{beam.get_downvalues.46}}</td>
385 251 <td {%if beam.pk == active_beam %} {{color_status.48}} {%endif%} title='{{module_messages.48}}'>{{beam.get_downvalues.47}}</td>
386 252 </tr>
387 253 <tr>
388 254 <td {%if beam.pk == active_beam %} {{color_status.53}} {%endif%} title='{{module_messages.53}}'>{{beam.get_upvalues.52}}</td>
389 255 <td {%if beam.pk == active_beam %} {{color_status.54}} {%endif%} title='{{module_messages.54}}'>{{beam.get_upvalues.53}}</td>
390 256 <td {%if beam.pk == active_beam %} {{color_status.55}} {%endif%} title='{{module_messages.55}}'>{{beam.get_upvalues.54}}</td>
391 257 <td {%if beam.pk == active_beam %} {{color_status.56}} {%endif%} title='{{module_messages.56}}'>{{beam.get_upvalues.55}}</td>
392 258 </tr>
393 259 <tr>
394 260 <td {%if beam.pk == active_beam %} {{color_status.53}} {%endif%} title='{{module_messages.53}}'>{{beam.get_downvalues.52}}</td>
395 261 <td {%if beam.pk == active_beam %} {{color_status.54}} {%endif%} title='{{module_messages.54}}'>{{beam.get_downvalues.53}}</td>
396 262 <td {%if beam.pk == active_beam %} {{color_status.55}} {%endif%} title='{{module_messages.55}}'>{{beam.get_downvalues.54}}</td>
397 263 <td {%if beam.pk == active_beam %} {{color_status.56}} {%endif%} title='{{module_messages.56}}'>{{beam.get_downvalues.55}}</td>
398 264 </tr>
399 265 <tr>
400 266 <td {%if beam.pk == active_beam %} {{color_status.61}} {%endif%} title='{{module_messages.61}}'>{{beam.get_upvalues.60}}</td>
401 267 <td {%if beam.pk == active_beam %} {{color_status.62}} {%endif%} title='{{module_messages.62}}'>{{beam.get_upvalues.61}}</td>
402 268 <td {%if beam.pk == active_beam %} {{color_status.63}} {%endif%} title='{{module_messages.63}}'>{{beam.get_upvalues.62}}</td>
403 269 <td {%if beam.pk == active_beam %} {{color_status.64}} {%endif%} title='{{module_messages.64}}'>{{beam.get_upvalues.63}}</td>
404 270 </tr>
405 271 <tr>
406 272 <td {%if beam.pk == active_beam %} {{color_status.61}} {%endif%} title='{{module_messages.61}}'>{{beam.get_downvalues.60}}</td>
407 273 <td {%if beam.pk == active_beam %} {{color_status.62}} {%endif%} title='{{module_messages.62}}'>{{beam.get_downvalues.61}}</td>
408 274 <td {%if beam.pk == active_beam %} {{color_status.63}} {%endif%} title='{{module_messages.63}}'>{{beam.get_downvalues.62}}</td>
409 275 <td {%if beam.pk == active_beam %} {{color_status.64}} {%endif%} title='{{module_messages.64}}'>{{beam.get_downvalues.63}}</td>
410 276 </tr>
411 277 </table>
412 278 </td>
413 279 </tr>
414 280 </table>
415 281
416 282 {% if beam.id == active_beam %}
417 283 <table class="legend">
418 284 <tr>
419 285 <th colspan="2">Legend</th>
420 286 </tr>
421 287 <tr>
422 288 <td class="text-danger">
423 289 <i>RED</i>
424 290 </td>
425 291 <td>Disconnected</td>
426 292 </tr>
427 293 <tr>
428 294 <td class="text-warning">
429 295 <i>ORANGE</i>
430 296 </td>
431 297 <td>Connected</td>
432 298 </tr>
433 299 <tr>
434 300 <td class="text-success">
435 301 <i>GREEN</i>
436 302 </td>
437 303 <td>Running
438 304 </td>
439 305 </tr>
440 306 </table>
441 307 {% else %}
442 308 <div style="vertical-align: top; display:inline-block;">
443 309 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
444 310 <span class="glyphicon glyphicon-export" aria-hidden="true"></span>
445 311 Change Beam</button>
446 312 </div>
447 313 {% endif %}
448 314 </div>
449 315 {% endfor %}
450 316 </div>
451 317 </div>
452 318
453 319
454 320 {% else %}
455 321 <p style="color:#b4bcc2; margin-left: 5%;">
456 322 <i>No Beams...</i>
457 323 </p>
458 324 {% endif %} {% endblock extra-content %} {% block extra-js%}
459 325 <script>
460 326 $(document).ready(function () {
461 327
462 328 {% for beam in beams %}
463 329
464 330 {% if dev_conf.operation_mode == 1 %}
465 331 $("#send_beam{{forloop.counter}}").prop('disabled', true)
466 332 {% else %}
467 333 $("#send_beam{{forloop.counter}}").click(function () {
468 334 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
469 335 });
470 336 {% endif %}
471 337
472 338 {% endfor %}
473 339
474 340
475 341 });
476 342 </script> {% endblock %} No newline at end of file
@@ -1,406 +1,406
1 1 from django.shortcuts import render_to_response
2 2 from django.template import RequestContext
3 3 from django.shortcuts import redirect, render, get_object_or_404
4 4 from django.contrib import messages
5 5 from django.conf import settings
6 6 from django.http import HttpResponse
7 7 from django.core.urlresolvers import reverse
8 8
9 9 from datetime import datetime
10 10 from time import sleep
11 11 import os
12 12 import io
13 13
14 14 from apps.main.models import Device, Configuration, Experiment
15 15 from apps.main.views import sidebar
16 16
17 17 from .models import ABSConfiguration, ABSBeam
18 18 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
19 19
20 20 from .utils.overJroShow import overJroShow
21 21 from .utils.OverJRO import OverJRO
22 22 # Create your views here.
23 23 import json, ast
24 24
25 25
26 26 def get_values_from_form(form_data):
27 27
28 28 sublistup = []
29 29 sublistdown = []
30 30 subtxlistup = []
31 31 subtxlistdown = []
32 32 subrxlistup = []
33 33 subrxlistdown = []
34 34
35 35 up_values_list = []
36 36 down_values_list = []
37 37 up_txvalues_list = []
38 38 down_txvalues_list = []
39 39 up_rxvalues_list = []
40 40 down_rxvalues_list = []
41 41
42 42 values_list = {}
43 43 cont = 1
44 44
45 45 for i in range(1,65):
46 46 x = float(form_data['abs_up'+str(i)])
47 47 y = float(form_data['abs_down'+str(i)])
48 48 sublistup.append(x)
49 49 sublistdown.append(y)
50 50
51 51 if str(i) in form_data.getlist('uptx_checks'):
52 52 subtxlistup.append(1)
53 53 else:
54 54 subtxlistup.append(0)
55 55 if str(i) in form_data.getlist('downtx_checks'):
56 56 subtxlistdown.append(1)
57 57 else:
58 58 subtxlistdown.append(0)
59 59
60 60 if str(i) in form_data.getlist('uprx_checks'):
61 61 subrxlistup.append(1)
62 62 else:
63 63 subrxlistup.append(0)
64 64 if str(i) in form_data.getlist('downrx_checks'):
65 65 subrxlistdown.append(1)
66 66 else:
67 67 subrxlistdown.append(0)
68 68
69 69 cont = cont+1
70 70
71 71 if cont == 9:
72 72 up_values_list.append(sublistup)
73 73 down_values_list.append(sublistdown)
74 74 sublistup = []
75 75 sublistdown = []
76 76
77 77 up_txvalues_list.append(subtxlistup)
78 78 down_txvalues_list.append(subtxlistdown)
79 79 subtxlistup = []
80 80 subtxlistdown = []
81 81 up_rxvalues_list.append(subrxlistup)
82 82 down_rxvalues_list.append(subrxlistdown)
83 83 subrxlistup = []
84 84 subrxlistdown = []
85 85 cont = 1
86 86
87 87
88 88 list_uesup = []
89 89 list_uesdown = []
90 90 for i in range(1,5):
91 91 if form_data['ues_up'+str(i)] == '':
92 92 list_uesup.append(0.0)
93 93 else:
94 94 list_uesup.append(float(form_data['ues_up'+str(i)]))
95 95
96 96 if form_data['ues_down'+str(i)] == '':
97 97 list_uesdown.append(0.0)
98 98 else:
99 99 list_uesdown.append(float(form_data['ues_down'+str(i)]))
100 100
101 101 onlyrx_list = form_data.getlist('onlyrx')
102 102 only_rx = {}
103 103 if '1' in onlyrx_list:
104 104 only_rx['up'] = True
105 105 else:
106 106 only_rx['up'] = False
107 107 if '2' in onlyrx_list:
108 108 only_rx['down'] = True
109 109 else:
110 110 only_rx['down'] = False
111 111
112 112 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
113 113 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
114 114 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
115 115 ues = {'up': list_uesup, 'down': list_uesdown}
116 116 name = str(form_data['beam_name'])
117 117
118 118 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
119 119
120 120 return beam_data
121 121
122 122
123 123 def abs_conf(request, id_conf):
124 124
125 125 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
126 126 beams = ABSBeam.objects.filter(abs_conf=conf)
127 127 #------------Colors for Active Beam:-------------
128 128 all_status = {}
129 129 module_messages = json.loads(conf.module_messages)
130 130
131 131 color_status = {}
132 132 for i, status in enumerate(conf.module_status):
133 133 if status == '3': #Running background-color: #00cc00;
134 134 all_status['{}'.format(i+1)] = 2
135 135 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
136 136 elif status == '1': #Connected background-color: #ee902c;
137 137 all_status['{}'.format(i+1)] = 1
138 138 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
139 139 else: #Disconnected background-color: #ff0000;
140 140 all_status['{}'.format(i+1)] = 0
141 141 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
142 142 #------------------------------------------------
143 143
144 144 kwargs = {}
145 145 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
146 146 kwargs['dev_conf'] = conf
147 147
148 148 if conf.operation_mode == 0:
149 kwargs['dev_conf_keys'] = ['name', 'operation_mode']
149 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
150 150 else:
151 kwargs['dev_conf_keys'] = ['name', 'operation_mode', 'operation_value']
151 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
152 152
153 153 kwargs['title'] = 'ABS Configuration'
154 154 kwargs['suptitle'] = 'Details'
155 155 kwargs['button'] = 'Edit Configuration'
156 156
157 157 if conf.active_beam != 0:
158 158 kwargs['active_beam'] = int(conf.active_beam)
159 159
160 160 kwargs['beams'] = beams
161 161 kwargs['modules_status'] = all_status
162 162 kwargs['color_status'] = color_status
163 163 kwargs['module_messages'] = module_messages
164 164 ###### SIDEBAR ######
165 165 kwargs.update(sidebar(conf=conf))
166 166
167 167 return render(request, 'abs_conf.html', kwargs)
168 168
169 169
170 170 def abs_conf_edit(request, id_conf):
171 171
172 172 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
173 173
174 174 beams = ABSBeam.objects.filter(abs_conf=conf)
175 175
176 176 if request.method=='GET':
177 177 form = ABSConfigurationForm(instance=conf)
178 178
179 179 if request.method=='POST':
180 180 form = ABSConfigurationForm(request.POST, instance=conf)
181 181
182 182 if form.is_valid():
183 183 conf = form.save(commit=False)
184 184 conf.save()
185 185 return redirect('url_abs_conf', id_conf=conf.id)
186 186
187 187 ###### SIDEBAR ######
188 188 kwargs = {}
189 189
190 190 kwargs['dev_conf'] = conf
191 191 #kwargs['id_dev'] = conf.id
192 192 kwargs['id_conf'] = conf.id
193 193 kwargs['form'] = form
194 194 kwargs['abs_beams'] = beams
195 195 kwargs['title'] = 'Device Configuration'
196 196 kwargs['suptitle'] = 'Edit'
197 197 kwargs['button'] = 'Save'
198 198
199 199 kwargs['edit'] = True
200 200
201 201 return render(request, 'abs_conf_edit.html', kwargs)
202 202
203 203
204 204 def import_file(request, id_conf):
205 205
206 206 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
207 207 if request.method=='POST':
208 208 form = ABSImportForm(request.POST, request.FILES)
209 209 if form.is_valid():
210 210 try:
211 211 parms = conf.import_from_file(request.FILES['file_name'])
212 212
213 213 if parms:
214 214 conf.update_from_file(parms)
215 215 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
216 216 return redirect(conf.get_absolute_url_edit())
217 217
218 218 except Exception as e:
219 219 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
220 220
221 221 else:
222 222 messages.warning(request, 'Your current configuration will be replaced')
223 223 form = ABSImportForm()
224 224
225 225 kwargs = {}
226 226 kwargs['form'] = form
227 227 kwargs['title'] = 'ABS Configuration'
228 228 kwargs['suptitle'] = 'Import file'
229 229 kwargs['button'] = 'Upload'
230 230 kwargs['previous'] = conf.get_absolute_url()
231 231
232 232 return render(request, 'abs_import.html', kwargs)
233 233
234 234
235 235 def send_beam(request, id_conf, id_beam):
236 236
237 237 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
238 238 beam = get_object_or_404(ABSBeam, pk=id_beam)
239 239 beams_list = ABSBeam.objects.filter(abs_conf=conf)
240 240 conf.active_beam = id_beam
241 241
242 242 i = 0
243 243 for b in beams_list:
244 244 if b.id == int(id_beam):
245 245 break
246 246 else:
247 247 i += 1
248 248 beam_pos = i + 1 #Estandarizar
249 249 print '%s Position: %s' % (beam.name, str(beam_pos))
250 250 conf.send_beam(beam_pos)
251 251
252 252 return redirect('url_abs_conf', conf.id)
253 253
254 254
255 255 def add_beam(request, id_conf):
256 256
257 257 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
258 258 confs = Configuration.objects.all()
259 259
260 260 if request.method=='GET':
261 261 form = ABSBeamAddForm()
262 262
263 263 if request.method=='POST':
264 264 form = ABSBeamAddForm(request.POST)
265 265
266 266 beam_data = get_values_from_form(request.POST)
267 267
268 268 new_beam = ABSBeam(
269 269 name = beam_data['name'],
270 270 antenna = json.dumps(beam_data['antenna']),
271 271 abs_conf = conf,
272 272 tx = json.dumps(beam_data['tx']),
273 273 rx = json.dumps(beam_data['rx']),
274 274 ues = json.dumps(beam_data['ues']),
275 275 only_rx = json.dumps(beam_data['only_rx'])
276 276 )
277 277 new_beam.save()
278 278 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
279 279
280 280 return redirect('url_edit_abs_conf', conf.id)
281 281
282 282 ###### SIDEBAR ######
283 283 kwargs = {}
284 284
285 285 #kwargs['dev_conf'] = conf.device
286 286 #kwargs['id_dev'] = conf.device
287 287 kwargs['id_conf'] = conf.id
288 288 kwargs['form'] = form
289 289 kwargs['title'] = 'ABS Beams'
290 290 kwargs['suptitle'] = 'Add Beam'
291 291 kwargs['button'] = 'Add'
292 292 kwargs['no_sidebar'] = True
293 293
294 294 #kwargs['previous'] = conf.get_absolute_url_edit()
295 295 kwargs['edit'] = True
296 296
297 297 return render(request, 'abs_add_beam.html', kwargs)
298 298
299 299
300 300 def edit_beam(request, id_conf, id_beam):
301 301
302 302 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
303 303 beam = get_object_or_404(ABSBeam, pk=id_beam)
304 304
305 305 if request.method=='GET':
306 306 form = ABSBeamEditForm(initial={'beam': beam})
307 307
308 308 if request.method=='POST':
309 309 form = ABSBeamEditForm(request.POST)
310 310
311 311 beam_data = get_values_from_form(request.POST)
312 312
313 313 beam.dict_to_parms(beam_data)
314 314 beam.save()
315 315
316 316 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
317 317
318 318 return redirect('url_edit_abs_conf', conf.id)
319 319
320 320 ###### SIDEBAR ######
321 321 kwargs = {}
322 322
323 323 kwargs['id_conf'] = conf.id
324 324 kwargs['form'] = form
325 325 kwargs['title'] = 'ABS Beams'
326 326 kwargs['suptitle'] = 'Edit Beam'
327 327 kwargs['button'] = 'Save'
328 328 kwargs['no_sidebar'] = True
329 329
330 330 #kwargs['previous'] = conf.get_absolute_url_edit()
331 331 kwargs['edit'] = True
332 332
333 333 return render(request, 'abs_edit_beam.html', kwargs)
334 334
335 335
336 336
337 337 def remove_beam(request, id_conf, id_beam):
338 338
339 339 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
340 340 beam = get_object_or_404(ABSBeam, pk=id_beam)
341 341
342 342 if request.method=='POST':
343 343 if beam:
344 344 try:
345 345 beam.remove_beamfromlist()
346 346 beam.delete()
347 347 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
348 348 except:
349 349 messages.error(request, 'Unable to delete beam: "%s".' % beam)
350 350
351 351 return redirect('url_edit_abs_conf', conf.id)
352 352
353 353 ###### SIDEBAR ######
354 354 kwargs = {}
355 355
356 356 kwargs['object'] = beam
357 357 kwargs['delete'] = True
358 358 kwargs['title'] = 'Delete'
359 359 kwargs['suptitle'] = 'Beam'
360 360 kwargs['previous'] = conf.get_absolute_url_edit()
361 361 return render(request, 'confirm.html', kwargs)
362 362
363 363
364 364
365 365 def plot_patterns(request, id_conf, id_beam=None):
366 366
367 367 kwargs = {}
368 368 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
369 369 beams = ABSBeam.objects.filter(abs_conf=conf)
370 370
371 371 if id_beam:
372 372 beam = get_object_or_404(ABSBeam, pk=id_beam)
373 373 kwargs['beam'] = beam
374 374
375 375 ###### SIDEBAR ######
376 376
377 377 kwargs['dev_conf'] = conf.device
378 378 kwargs['id_dev'] = conf.device
379 379 kwargs['id_conf'] = conf.id
380 380 kwargs['abs_beams'] = beams
381 381 kwargs['title'] = 'ABS Patterns'
382 382 kwargs['suptitle'] = conf.name
383 383 kwargs['no_sidebar'] = True
384 384
385 385 return render(request, 'abs_patterns.html', kwargs)
386 386
387 387
388 388 def plot_pattern(request, id_conf, id_beam, antenna):
389 389
390 390 if antenna=='down':
391 391 sleep(3)
392 392
393 393 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
394 394 beam = get_object_or_404(ABSBeam, pk=id_beam)
395 395 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
396 396 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
397 397 gain_tx = json.loads(beam.tx)[antenna]
398 398 gain_rx = json.loads(beam.rx)[antenna]
399 399 ues = json.loads(beam.ues)[antenna]
400 400 newOverJro = overJroShow(beam.name)
401 401 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
402 402 buf = io.BytesIO()
403 403 fig.savefig(buf, format='png')
404 404 response = HttpResponse(buf.getvalue(), content_type='image/png')
405 405 return response
406 406 No newline at end of file
@@ -1,33 +1,32
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import CGSConfiguration
4 4
5 5 class CGSConfigurationForm(forms.ModelForm):
6 6
7 7 def __init__(self, *args, **kwargs):
8 8 #request = kwargs.pop('request')
9 9 super(CGSConfigurationForm, self).__init__(*args, **kwargs)
10 10
11 11 instance = getattr(self, 'instance', None)
12 12
13 13 if instance and instance.pk:
14 14
15 15 devices = Device.objects.filter(device_type__name='cgs')
16 16
17 17 if instance.experiment:
18 18 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
19 19
20 20 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
21 21
22 22 def clean(self):
23 23 return
24 24
25 25 class Meta:
26 26 model = CGSConfiguration
27 exclude = ('type', 'parameters', 'status')
28 #fields = ('experiment', 'device', 'freq0', 'freq1', 'freq2', 'freq3')
27 exclude = ('type', 'parameters', 'status', 'author', 'hash')
29 28
30 29
31 30 class UploadFileForm(forms.Form):
32 31 title = forms.CharField(label='Extension Type', widget=forms.TextInput(attrs={'readonly':'readonly'}))
33 32 file = forms.FileField()
@@ -1,27 +1,27
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import DDSConfiguration
4 4
5 5 # from django.core.validators import MinValueValidator, MaxValueValidator
6 6
7 7 class DDSConfigurationForm(forms.ModelForm):
8 8
9 9 def __init__(self, *args, **kwargs):
10 10
11 11 super(DDSConfigurationForm, self).__init__(*args, **kwargs)
12 12
13 13 instance = getattr(self, 'instance', None)
14 14
15 15 if instance and instance.pk:
16 16
17 17 devices = Device.objects.filter(device_type__name='dds')
18 18
19 19 #if instance.experiment:
20 20 # self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
21 21
22 22 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
23 23
24 24
25 25 class Meta:
26 26 model = DDSConfiguration
27 exclude = ('type', 'parameters', 'status') No newline at end of file
27 exclude = ('type', 'parameters', 'status', 'author', 'hash') No newline at end of file
@@ -1,74 +1,74
1 1 # Create your views here.
2 2 from django.shortcuts import redirect, render, get_object_or_404
3 3
4 4 # from apps.main.models import Experiment, Configuration
5 5 from apps.main.views import sidebar
6 6
7 7 from .models import DDSConfiguration
8 8 from .forms import DDSConfigurationForm
9 9 # Create your views here.
10 10
11 11 def dds_conf(request, id_conf):
12 12
13 13 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
14 14
15 15 kwargs = {}
16 16
17 17 kwargs['status'] = conf.device.get_status_display()
18 18
19 19 # if not kwargs['connected']:
20 20 # messages.error(request, message=answer)
21 21
22 22 kwargs['dev_conf'] = conf
23 kwargs['dev_conf_keys'] = ['name',
23 kwargs['dev_conf_keys'] = [
24 24 'clock',
25 25 'multiplier',
26 26 'frequencyA_Mhz',
27 27 'frequencyA',
28 28 'frequencyB_Mhz',
29 29 'frequencyB',
30 30 'phaseA_degrees',
31 31 'phaseB_degrees',
32 32 'modulation',
33 33 'amplitude_enabled',
34 34 'amplitudeI',
35 35 'amplitudeQ']
36 36
37 37 kwargs['title'] = 'DDS Configuration'
38 38 kwargs['suptitle'] = 'Details'
39 39
40 40 kwargs['button'] = 'Edit Configuration'
41 41
42 42 ###### SIDEBAR ######
43 43 kwargs.update(sidebar(conf=conf))
44 44
45 45 return render(request, 'dds_conf.html', kwargs)
46 46
47 47 def dds_conf_edit(request, id_conf):
48 48
49 49 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
50 50
51 51 if request.method=='GET':
52 52 form = DDSConfigurationForm(instance=conf)
53 53
54 54 if request.method=='POST':
55 55 form = DDSConfigurationForm(request.POST, instance=conf)
56 56
57 57 if form.is_valid():
58 58 conf = form.save(commit=False)
59 59
60 60 if conf.verify_frequencies():
61 61
62 62 conf.save()
63 63 return redirect('url_dds_conf', id_conf=conf.id)
64 64
65 65 ##ERRORS
66 66
67 67 kwargs = {}
68 68 kwargs['id_dev'] = conf.id
69 69 kwargs['form'] = form
70 70 kwargs['title'] = 'Device Configuration'
71 71 kwargs['suptitle'] = 'Edit'
72 72 kwargs['button'] = 'Save'
73 73
74 74 return render(request, 'dds_conf_edit.html', kwargs)
@@ -1,7 +1,7
1 1 from django.contrib import admin
2 from .models import JARSConfiguration, JARSfilter
2 from .models import JARSConfiguration, JARSFilter
3 3
4 4 # Register your models here.
5 5
6 6 admin.site.register(JARSConfiguration)
7 admin.site.register(JARSfilter)
7 admin.site.register(JARSFilter)
@@ -1,3 +1,30
1 [{"fields": {"name": "49_92MHz_clock60MHz_F1KHz_12_25_2", "clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 2, "filter_2": 12, "filter_5": 25}, "model": "jars.jarsfilter", "pk": 1},
2 {"fields": {"name": "49_920MHz_clock60MHz_F1MHz_10_1_6", "clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 6, "filter_2": 10, "filter_5": 1}, "model": "jars.jarsfilter", "pk": 2}
3 ]
1 [
2 {
3 "fields": {
4 "name": "49_92MHz_clock60MHz_F1KHz_12_25_2",
5 "clock": 60,
6 "multiplier": 5,
7 "frequency": 49.92,
8 "f_decimal": 721554506,
9 "fir": 2,
10 "cic_2": 12,
11 "cic_5": 25
12 },
13 "model": "jars.jarsfilter",
14 "pk": 1
15 },
16 {
17 "fields": {
18 "name": "49_920MHz_clock60MHz_F1MHz_10_1_6",
19 "clock": 60,
20 "multiplier": 5,
21 "frequency": 49.92,
22 "f_decimal": 721554506,
23 "fir": 6,
24 "cic_2": 10,
25 "cic_5": 1
26 },
27 "model": "jars.jarsfilter",
28 "pk": 2
29 }
30 ] No newline at end of file
@@ -1,115 +1,102
1 1 import os
2 2
3 3 from django import forms
4 4 from apps.main.models import Device, Experiment
5 from .models import JARSConfiguration, JARSfilter
5 from .models import JARSConfiguration, JARSFilter
6 6 from .widgets import SpectralWidget
7 7 from apps.main.forms import add_empty_choice
8 8
9 9 def create_choices_from_model(model, filter_id=None):
10 10
11 11 #instance = globals()[model]
12 12 choices = model.objects.all().values_list('pk', 'name')
13 13 choices = add_empty_choice(choices)
14 14 return choices
15 15
16 16 class JARSConfigurationForm(forms.ModelForm):
17 17 def __init__(self, *args, **kwargs):
18 18 super(JARSConfigurationForm, self).__init__(*args, **kwargs)
19 19 instance = getattr(self, 'instance', None)
20 20
21 21 if instance and instance.pk:
22 22 devices = Device.objects.filter(device_type__name='jars')
23
24 #if instance.experiment:
25 # experiments = Experiment.objects.filter(pk=instance.experiment.id)
26 # self.fields['experiment'].widget.choices = [(experiment.id, experiment) for experiment in experiments]
27
28 23 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
29 #self.fields['spectral'].widget = SpectralWidget()
30 24 self.fields['spectral_number'].widget.attrs['readonly'] = True
31 25 self.fields['spectral'].widget = SpectralWidget()
32 26
33 #-------------JARS Configuration needs an Experiment-----------------
34 #def clean(self):
35 # cleaned_data = super(JARSConfigurationForm, self).clean()
36 # experiment = cleaned_data.get('experiment')
37 # if not experiment:
38 # msg = "Error: Jars Configuration needs an Experiment"
39 # self.add_error('experiment', msg)
40
41 27 class Meta:
42 28 model = JARSConfiguration
43 exclude = ('type', 'parameters', 'status', 'filter_parms')
44
29 exclude = ('type', 'parameters', 'status', 'filter_parms', 'author', 'hash', 'filter')
45 30
46 class JARSfilterForm(forms.ModelForm):
31 class JARSFilterForm(forms.ModelForm):
47 32 def __init__(self, *args, **kwargs):
48 super(JARSfilterForm, self).__init__(*args, **kwargs)
33 super(JARSFilterForm, self).__init__(*args, **kwargs)
49 34 instance = getattr(self, 'instance', None)
50 35
51 self.fields['fch_decimal'].widget.attrs['readonly'] = True
36 self.fields['f_decimal'].widget.attrs['readonly'] = True
52 37
53 38 if 'initial' in kwargs:
54 if 'filter_id' not in kwargs['initial']:
55 self.fields.pop('name')
56 else:
57 self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSfilter))
58 filter_id = kwargs['initial']['filter_id']
59
60 if filter_id == 0:
61 for value in self.fields:
62 if value != 'name':
63 self.fields.pop(value)
64 self.fields['name'].label = "Filter Template Name"
65 else:
66 self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSfilter, kwargs['initial']['filter_id']))
67 jars_filter = JARSfilter.objects.get(pk=kwargs['initial']['filter_id'])
68 labels = [f.name for f in jars_filter._meta.get_fields()]
69
70 for label in ['id']:
71 labels.remove(label)
72 for label in labels:
73 self.fields['name'].initial = kwargs['initial']['filter_id']
74 self.fields[label].initial = getattr(jars_filter,label)
75 self.fields['name'].label = "Filter Template Name"
39 self.fields['filter_template'] = forms.ChoiceField(
40 choices=create_choices_from_model(JARSFilter),
41 initial = kwargs['initial']['id']
42 )
43 # self.fields['name'].initial = kwargs['initial']['id']
44
45 # filter_id = kwargs['initial']['filter_id']
46
47 # if filter_id == 0:
48 # for value in self.fields:
49 # if value != 'name':
50 # self.fields.pop(value)
51 # self.fields['name'].label = "Filter Template Name"
52 # else:
53 # self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSFilter, kwargs['initial']['filter_id']))
54 # jars_filter = JARSFilter.objects.get(pk=kwargs['initial']['filter_id'])
55 # labels = [f.name for f in jars_filter._meta.get_fields()]
56
57 # for label in ['id']:
58 # labels.remove(label)
59 # for label in labels:
60 # self.fields['name'].initial = kwargs['initial']['filter_id']
61 # self.fields[label].initial = getattr(jars_filter,label)
62 # self.fields['name'].label = "Filter Template Name"
76 63
77 64 class Meta:
78 model = JARSfilter
79 exclude = ('type', 'parameters', 'status')
65 model = JARSFilter
66 exclude = ('name', )
80 67
81 68
82 69 class ExtFileField(forms.FileField):
83 70 """
84 71 Same as forms.FileField, but you can specify a file extension whitelist.
85 72
86 73 >>> from django.core.files.uploadedfile import SimpleUploadedFile
87 74 >>>
88 75 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
89 76 >>>
90 77 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
91 78 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
92 79 >>>
93 80 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
94 81 Traceback (most recent call last):
95 82 ...
96 83 ValidationError: [u'Not allowed filetype!']
97 84 """
98 85 def __init__(self, *args, **kwargs):
99 86 extensions = kwargs.pop("extensions")
100 87 self.extensions = [i.lower() for i in extensions]
101 88
102 89 super(ExtFileField, self).__init__(*args, **kwargs)
103 90
104 91 def clean(self, *args, **kwargs):
105 92 data = super(ExtFileField, self).clean(*args, **kwargs)
106 93 filename = data.name
107 94 ext = os.path.splitext(filename)[1]
108 95 ext = ext.lower()
109 96 if ext not in self.extensions:
110 97 raise forms.ValidationError('Not allowed file type: %s' % ext)
111 98
112 99
113 100 class JARSImportForm(forms.Form):
114 101
115 102 file_name = ExtFileField(extensions=['.racp','.json'])
@@ -1,335 +1,389
1 1 import json
2 2 import requests
3 3
4 4 from django.db import models
5 5 from django.core.validators import MinValueValidator, MaxValueValidator
6 6 from django.core.urlresolvers import reverse
7 7
8 8 from apps.main.models import Configuration
9 9 from apps.main.utils import Params
10 10 from .utils import create_jarsfiles
11 11
12 12 # Create your models here.
13 13
14 14 EXPERIMENT_TYPE = (
15 (0, 'RAW_DATA'),
16 (1, 'PDATA'),
17 )
15 (0, 'RAW_DATA'),
16 (1, 'PDATA'),
17 )
18 18
19 19 DATA_TYPE = (
20 (0, 'SHORT'),
21 (1, 'FLOAT'),
22 )
20 (0, 'SHORT'),
21 (1, 'FLOAT'),
22 )
23 23
24 24 DECODE_TYPE = (
25 (0, 'None'),
26 (1, 'TimeDomain'),
27 (2, 'FreqDomain'),
28 (3, 'InvFreqDomain'),
29 )
25 (0, 'None'),
26 (1, 'TimeDomain'),
27 (2, 'FreqDomain'),
28 (3, 'InvFreqDomain'),
29 )
30 30
31 class JARSfilter(models.Model):
31 FILTER = '{"id":1, "clock": 60, "multiplier": 5, "frequency": 49.92, "f_decimal": 721554506, "fir": 2, "cic_2": 12, "cic_5": 25}'
32
33 class JARSFilter(models.Model):
32 34
33 35 JARS_NBITS = 32
34 36
35 name = models.CharField(max_length=60, unique=True, default='')
36 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
37 mult = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=5)
38 fch = models.FloatField(verbose_name='Frequency (MHz)', validators=[MaxValueValidator(150)], null=True, default=49.9200)
39 fch_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)',validators=[MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
40 filter_2 = models.PositiveIntegerField(verbose_name='Filter 2',validators=[MinValueValidator(2), MaxValueValidator(100)], default = 10)
41 filter_5 = models.PositiveIntegerField(verbose_name='Filter 5',validators=[MinValueValidator(1), MaxValueValidator(100)], default = 1)
42 filter_fir = models.PositiveIntegerField(verbose_name='FIR Filter',validators=[MinValueValidator(1), MaxValueValidator(100)], default = 6)
37 name = models.CharField(verbose_name='Name', max_length=60, unique=True, default='')
38 clock = models.FloatField(verbose_name='Clock In (MHz)', validators=[
39 MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
40 multiplier = models.PositiveIntegerField(verbose_name='Multiplier', validators=[
41 MinValueValidator(1), MaxValueValidator(20)], default=5)
42 frequency = models.FloatField(verbose_name='Frequency (MHz)', validators=[
43 MaxValueValidator(150)], null=True, default=49.9200)
44 f_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)', validators=[
45 MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
46 cic_2 = models.PositiveIntegerField(verbose_name='CIC2', validators=[
47 MinValueValidator(2), MaxValueValidator(100)], default=10)
48 scale_cic_2 = models.PositiveIntegerField(verbose_name='Scale CIC2', validators=[
49 MinValueValidator(0), MaxValueValidator(6)], default=1)
50 cic_5 = models.PositiveIntegerField(verbose_name='CIC5', validators=[
51 MinValueValidator(1), MaxValueValidator(100)], default=1)
52 scale_cic_5 = models.PositiveIntegerField(verbose_name='Scale CIC5', validators=[
53 MinValueValidator(0), MaxValueValidator(20)], default=5)
54 fir = models.PositiveIntegerField(verbose_name='FIR', validators=[
55 MinValueValidator(1), MaxValueValidator(100)], default=6)
56 scale_fir = models.PositiveIntegerField(verbose_name='Scale FIR', validators=[
57 MinValueValidator(0), MaxValueValidator(7)], default=3)
58 number_taps = models.PositiveIntegerField(verbose_name='Number of taps', validators=[
59 MinValueValidator(1), MaxValueValidator(256)], default=4)
60 taps = models.CharField(verbose_name='Taps', max_length=256, default='')
43 61
44 62 class Meta:
45 63 db_table = 'jars_filters'
46 64
47 65 def __unicode__(self):
48 66 return u'%s' % (self.name)
49 67
68 def jsonify(self):
69
70 data = {}
71 ignored = ()
72
73 for field in self._meta.fields:
74 if field.name in ignored:
75 continue
76 data[field.name] = field.value_from_object(self)
77
78 return data
79
50 80 def parms_to_dict(self):
51 81
52 82 parameters = {}
53 83
54 #parameters['name'] = self.name
55 parameters['clock'] = float(self.clock)
56 parameters['mult'] = int(self.mult)
57 parameters['fch'] = float(self.fch)
58 parameters['fch_decimal'] = int(self.fch)
59 parameters['filter_fir'] = int(self.filter_fir)
60 parameters['filter_2'] = int(self.filter_2)
61 parameters['filter_5'] = int(self.filter_5)
84 parameters['name'] = self.name
85 parameters['clock'] = float(self.clock)
86 parameters['multiplier'] = int(self.multiplier)
87 parameters['frequency'] = float(self.frequency)
88 parameters['f_decimal'] = int(self.frequency)
89 parameters['fir'] = int(self.fir)
90 parameters['cic_2'] = int(self.cic_2)
91 parameters['cic_5'] = int(self.cic_5)
62 92
63 93 return parameters
64 94
65 95 def dict_to_parms(self, parameters):
66 96
67 #self.name = parameters['name']
68 self.clock = parameters['clock']
69 self.mult = parameters['mult']
70 self.fch = parameters['fch']
71 self.fch_decimal = parameters['fch_decimal']
72 self.filter_fir = parameters['filter_fir']
73 self.filter_2 = parameters['filter_2']
74 self.filter_5 = parameters['filter_5']
97 self.name = parameters['name']
98 self.clock = parameters['clock']
99 self.multiplier = parameters['multiplier']
100 self.frequency = parameters['frequency']
101 self.f_decimal = parameters['f_decimal']
102 self.fir = parameters['fir']
103 self.cic_2 = parameters['cic_2']
104 self.cic_5 = parameters['cic_5']
75 105
76 106
77 107 class JARSConfiguration(Configuration):
78 108
79 ADC_RESOLUTION = 8
109 ADC_RESOLUTION = 8
80 110 PCI_DIO_BUSWIDTH = 32
81 HEADER_VERSION = 1103
82 BEGIN_ON_START = True
83 REFRESH_RATE = 1
84
85 exp_type = models.PositiveIntegerField(verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
86 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[MinValueValidator(1), MaxValueValidator(4)], default = 1)
87 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[MinValueValidator(1), MaxValueValidator(8)], default = 5)
88 channels = models.CharField(verbose_name='Channels', max_length=15, default = '1,2,3,4,5')
89 data_type = models.PositiveIntegerField(verbose_name='Data Type', choices=DATA_TYPE, default=0)
90 raw_data_blocks = models.PositiveIntegerField(verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
91 profiles_block = models.PositiveIntegerField(verbose_name='Profiles Per Block', default=400)
92 acq_profiles = models.PositiveIntegerField(verbose_name='Acquired Profiles', default=400)
93 ftp_interval = models.PositiveIntegerField(verbose_name='FTP Interval', default=60)
94 fftpoints = models.PositiveIntegerField(verbose_name='FFT Points',default=16)
95 cohe_integr_str = models.PositiveIntegerField(verbose_name='Coh. Int. Stride',validators=[MinValueValidator(1)], default=30)
96 cohe_integr = models.PositiveIntegerField(verbose_name='Coherent Integrations',validators=[MinValueValidator(1)], default=30)
97 incohe_integr = models.PositiveIntegerField(verbose_name='Incoherent Integrations',validators=[MinValueValidator(1)], default=30)
98 decode_data = models.PositiveIntegerField(verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
99 post_coh_int = models.BooleanField(verbose_name='Post Coherent Integration', default=False)
100 spectral_number = models.PositiveIntegerField(verbose_name='# Spectral Combinations',validators=[MinValueValidator(1)], default=1)
101 spectral = models.CharField(verbose_name='Combinations', max_length=5000, default = '[0, 0],')
102 create_directory = models.BooleanField(verbose_name='Create Directory Per Day', default=True)
103 include_expname = models.BooleanField(verbose_name='Experiment Name in Directory', default=False)
111 HEADER_VERSION = 1103
112 BEGIN_ON_START = True
113 REFRESH_RATE = 1
114
115 exp_type = models.PositiveIntegerField(
116 verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
117 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[
118 MinValueValidator(1), MaxValueValidator(4)], default=1)
119 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[
120 MinValueValidator(1), MaxValueValidator(8)], default=5)
121 channels = models.CharField(
122 verbose_name='Channels', max_length=15, default='1,2,3,4,5')
123 data_type = models.PositiveIntegerField(
124 verbose_name='Data Type', choices=DATA_TYPE, default=0)
125 raw_data_blocks = models.PositiveIntegerField(
126 verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
127 profiles_block = models.PositiveIntegerField(
128 verbose_name='Profiles Per Block', default=400)
129 acq_profiles = models.PositiveIntegerField(
130 verbose_name='Acquired Profiles', default=400)
131 ftp_interval = models.PositiveIntegerField(
132 verbose_name='FTP Interval', default=60)
133 fftpoints = models.PositiveIntegerField(
134 verbose_name='FFT Points', default=16)
135 cohe_integr_str = models.PositiveIntegerField(
136 verbose_name='Coh. Int. Stride', validators=[MinValueValidator(1)], default=30)
137 cohe_integr = models.PositiveIntegerField(
138 verbose_name='Coherent Integrations', validators=[MinValueValidator(1)], default=30)
139 incohe_integr = models.PositiveIntegerField(
140 verbose_name='Incoherent Integrations', validators=[MinValueValidator(1)], default=30)
141 decode_data = models.PositiveIntegerField(
142 verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
143 post_coh_int = models.BooleanField(
144 verbose_name='Post Coherent Integration', default=False)
145 spectral_number = models.PositiveIntegerField(
146 verbose_name='# Spectral Combinations', validators=[MinValueValidator(1)], default=1)
147 spectral = models.CharField(
148 verbose_name='Combinations', max_length=5000, default='[0, 0],')
149 create_directory = models.BooleanField(
150 verbose_name='Create Directory Per Day', default=True)
151 include_expname = models.BooleanField(
152 verbose_name='Experiment Name in Directory', default=False)
104 153 #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True)
105 save_ch_dc = models.BooleanField(verbose_name='Save Channels DC', default=True)
106 save_data = models.BooleanField(verbose_name='Save Data', default=True)
107 filter_parms = models.CharField(max_length=10000, default='{"clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 2, "filter_2": 12, "filter_5": 25}')
154 save_ch_dc = models.BooleanField(
155 verbose_name='Save Channels DC', default=True)
156 save_data = models.BooleanField(verbose_name='Save Data', default=True)
157 filter_parms = models.CharField(
158 max_length=10000, default=FILTER)
159 filter = models.ForeignKey(
160 'JARSFilter', verbose_name='Filter', null=True, blank=True, on_delete=models.CASCADE)
108 161
109 162 class Meta:
110 163 db_table = 'jars_configurations'
111 164
112 165 def filter_resolution(self):
113 filter_parms = eval(self.filter_parms)
114 if filter_parms.__class__.__name__=='str':
115 filter_parms = eval(filter_parms)
116
117 filter_clock = float(filter_parms['clock'])
118 filter_2 = filter_parms['filter_2']
119 filter_5 = filter_parms['filter_5']
120 filter_fir = filter_parms['filter_fir']
121
122 resolution = round((filter_clock/(filter_2*filter_5*filter_fir)),2)
166 filter_parms = json.loads(self.filter_parms)
167 clock = float(filter_parms['clock'])
168 cic_2 = filter_parms['cic_2']
169 cic_5 = filter_parms['cic_5']
170 fir = filter_parms['fir']
171 resolution = round((clock/(cic_2*cic_5*fir)), 2)
123 172 return resolution
124 173
125 174 def dict_to_parms(self, params, id=None):
126
175
127 176 if id is not None:
128 177 data = Params(params).get_conf(id_conf=id)
129 178 else:
130 179 data = Params(params).get_conf(dtype='jars')
131 180 data['filter_parms'] = params['filter_parms']
132
133 self.name = data['name']
134 self.exp_type = data['exp_type']
181
182 # self.name = data['name']
183 self.exp_type = data['exp_type']
135 184 #----PDATA----
136 185 if self.exp_type == 1:
137 self.incohe_integr = data['incohe_integr']
186 self.incohe_integr = data['incohe_integr']
138 187 self.spectral_number = data['spectral_number']
139 self.spectral = data['spectral']
140 self.fftpoints = data['fftpoints']
141 self.save_ch_dc = data['save_ch_dc']
188 self.spectral = data['spectral']
189 self.fftpoints = data['fftpoints']
190 self.save_ch_dc = data['save_ch_dc']
142 191 else:
143 192 self.raw_data_blocks = data['raw_data_blocks']
144 #----PDATA----
145 self.cards_number = data['cards_number']
193 #----PDATA----
194 self.cards_number = data['cards_number']
146 195 self.channels_number = data['channels_number']
147 self.channels = data['channels']
148 self.data_type = data['data_type']
149 self.profiles_block = data['profiles_block']
150 self.acq_profiles = data['acq_profiles']
151 self.ftp_interval = data['ftp_interval']
196 self.channels = data['channels']
197 self.data_type = data['data_type']
198 self.profiles_block = data['profiles_block']
199 self.acq_profiles = data['acq_profiles']
200 self.ftp_interval = data['ftp_interval']
152 201 self.cohe_integr_str = data['cohe_integr_str']
153 self.cohe_integr = data['cohe_integr']
202 self.cohe_integr = data['cohe_integr']
154 203 #----DECODE----
155 self.decode_data = data['decode_data']
156 self.post_coh_int = data['post_coh_int']
204 self.decode_data = data['decode_data']
205 self.post_coh_int = data['post_coh_int']
157 206 #----DECODE----
158 207 self.create_directory = data['create_directory']
159 self.include_expname = data['include_expname']
160 self.save_data = data['save_data']
161 self.filter_parms = json.dumps(data['filter_parms'])
162
208 self.include_expname = data['include_expname']
209 self.save_data = data['save_data']
210 self.filter_parms = json.dumps(data['filter_parms'])
211
163 212 self.save()
164 213
165 214 def parms_to_text(self, file_format='jars'):
166 215
167 216 data = self.experiment.parms_to_dict()
168 217
169 218 for key in data['configurations']['allIds']:
170 219 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
171 220 data['configurations']['allIds'].remove(key)
172 221 data['configurations']['byId'].pop(key)
173 222 elif data['configurations']['byId'][key]['device_type'] == 'jars':
174 data['configurations']['byId'][key] = self.parms_to_dict()['configurations']['byId'][str(self.pk)]
223 data['configurations']['byId'][key] = self.parms_to_dict(
224 )['configurations']['byId'][str(self.pk)]
175 225 elif data['configurations']['byId'][key]['device_type'] == 'rc':
176 226 data['configurations']['byId'][key]['pulses'] = ''
177 227 data['configurations']['byId'][key]['delays'] = ''
178 rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc']
179 mix_ids = [pk for pk in rc_ids if data['configurations']['byId'][pk]['mix']]
180
228 rc_ids = [pk for pk in data['configurations']['allIds']
229 if data['configurations']['byId'][pk]['device_type'] == 'rc']
230 mix_ids = [pk for pk in rc_ids if data['configurations']
231 ['byId'][pk]['mix']]
232
181 233 if mix_ids:
182 234 params = data['configurations']['byId'][mix_ids[0]]['parameters']
183 rc = data['configurations']['byId'][params.split('-')[0].split('|')[0]]
235 rc = data['configurations']['byId'][params.split(
236 '-')[0].split('|')[0]]
184 237 rc['mix'] = True
185 238 data['configurations']['byId'][rc['id']] = rc
186 elif len(rc_ids)==0:
239 elif len(rc_ids) == 0:
187 240 self.message = 'File needs RC configuration'
188 241 return ''
189 242
190 243 json_data = json.dumps(data)
191 244 racp_file, filter_file = create_jarsfiles(json_data)
192 if file_format=='racp':
245 if file_format == 'racp':
193 246 return racp_file
194 247
195 248 return filter_file
196 249
197 250 def request(self, cmd, method='get', **kwargs):
198 251
199 252 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
200 253 payload = req.json()
201 254 return payload
202 255
203 256 def status_device(self):
204 257
205 258 try:
206 259 payload = self.request('status',
207 260 params={'name': self.experiment.name})
208 261 self.device.status = payload['status']
209 262 self.device.save()
210 263 self.message = payload['message']
211 264 except Exception as e:
212 265 self.device.status = 0
213 266 self.message = str(e)
214 267 self.device.save()
215 268 return False
216 269
217 270 return True
218 271
219 272 def stop_device(self):
220 273
221 274 try:
222 275 payload = self.request('stop', 'post')
223 276 self.device.status = payload['status']
224 277 self.device.save()
225 278 self.message = payload['message']
226 279 except Exception as e:
227 280 self.device.status = 0
228 281 self.message = str(e)
229 282 self.device.save()
230 283 return False
231 284
232 285 return True
233 286
234 287 def read_device(self):
235 288
236 289 try:
237 payload = self.request('read', params={'name': self.experiment.name})
290 payload = self.request(
291 'read', params={'name': self.experiment.name})
238 292 self.message = 'Configuration loaded'
239 293 except:
240 294 self.device.status = 0
241 295 self.device.save()
242 296 self.message = 'Could not read JARS configuration.'
243 297 return False
244 298
245 299 return payload
246 300
247 301 def write_device(self):
248 302
249 303 if self.device.status == 3:
250 304 self.message = 'Could not configure device. Software Acquisition is running'
251 305 return False
252 306
253 307 data = self.experiment.parms_to_dict()
254 308
255 309 for key in data['configurations']['allIds']:
256 310 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
257 311 data['configurations']['allIds'].remove(key)
258 312 data['configurations']['byId'].pop(key)
259 313 elif data['configurations']['byId'][key]['device_type'] == 'rc':
260 314 data['configurations']['byId'][key]['pulses'] = ''
261 315 data['configurations']['byId'][key]['delays'] = ''
262 rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc']
263 if len(rc_ids)==0:
316 rc_ids = [pk for pk in data['configurations']['allIds']
317 if data['configurations']['byId'][pk]['device_type'] == 'rc']
318 if len(rc_ids) == 0:
264 319 self.message = 'Missing RC configuration'
265 320 return False
266 321
267 322 json_data = json.dumps(data)
268
323
269 324 try:
270 325 payload = self.request('write', 'post', json=json_data)
271 326 self.device.status = payload['status']
272 327 self.message = payload['message']
273 328 self.device.save()
274 329 if self.device.status == 1:
275 330 return False
276 331
277 332 except Exception as e:
278 333 self.device.status = 0
279 334 self.message = str(e)
280 335 self.device.save()
281 336 return False
282 337
283 338 return True
284 339
285 340 def start_device(self):
286 341
287 342 try:
288 343 payload = self.request('start', 'post',
289 344 json={'name': self.experiment.name})
290 345 self.device.status = payload['status']
291 346 self.message = payload['message']
292 347 self.device.save()
293 348 if self.device.status == 1:
294 349 return False
295 350
296 351 except Exception as e:
297 352 self.device.status = 0
298 353 self.message = str(e)
299 354 self.device.save()
300 355 return False
301 356
302 357 return True
303 358
304
305 359 def get_log(self):
306 360
307 361 payload = None
308 362
309 363 try:
310 payload = requests.get(self.device.url('get_log'), params={'name':self.experiment.name})
364 payload = requests.get(self.device.url('get_log'), params={
365 'name': self.experiment.name})
311 366 except:
312 367 self.device.status = 0
313 368 self.device.save()
314 369 self.message = 'Jars API is not running.'
315 370 return False
316
371
317 372 self.message = 'Jars API is running'
318 373
319 374 return payload
320 375
321
322 376 def update_from_file(self, filename):
323 377
324 378 f = JARSFile(filename)
325 379 self.dict_to_parms(f.data)
326 380 self.save()
327 381
328 382 def get_absolute_url_import(self):
329 383 return reverse('url_import_jars_conf', args=[str(self.id)])
330 384
331 385 def get_absolute_url_read(self):
332 386 return reverse('url_read_jars_conf', args=[str(self.id)])
333 387
334 388 def get_absolute_url_log(self):
335 389 return reverse('url_get_jars_log', args=[str(self.id)])
@@ -1,30 +1,29
1 $("#id_fch").change(function() {
1 $("#id_frequency").change(function() {
2 2 updateParameters()
3 3 });
4 4
5 5 $("#id_clock").change(function() {
6 6 updateParameters()
7 7 });
8 8
9 $("#id_mult").change(function() {
9 $("#id_multiplier").change(function() {
10 10 updateParameters()
11 11 });
12 12
13 13 function updateParameters(){
14 var fclock = $("#id_clock").val(); // clock frequency (MHz)
15 var fch = $("#id_fch").val(); // RF frequency (MHz)
16 var m_dds = $("#id_mult").val(); // DDS multiplier
14 var clock = $("#id_clock").val(); // clock frequency (MHz)
15 var fch = $("#id_frequency").val(); // RF frequency (MHz)
16 var m_dds = $("#id_multiplier").val(); // DDS multiplier
17 17
18 if (Math.abs(fch) < fclock/2){ // Si se cumple nyquist
19 var nco = Math.pow(2,32)*((fch/fclock)%1);
18 if (Math.abs(fch) < clock/2){ // Si se cumple nyquist
19 var nco = Math.pow(2,32)*((fch/clock)%1);
20 20 //var nco_i = Math.round(nco/m_dds)*m_dds;
21 21 var nco_i = Math.round(nco)
22 22 }
23 23 else {
24 nco = Math.pow(2,32)*(fclock-fch)/(fclock);
24 nco = Math.pow(2,32)*(clock-fch)/(clock);
25 25 //nco_i = Math.round(nco/m_dds)*m_dds;
26 26 var nco_i = Math.round(nco)
27 27 }
28 fch_decimal = $("#id_fch_decimal")
29 $(fch_decimal).val(nco_i)
28 $("#id_f_decimal").val(nco_i)
30 29 }
@@ -1,19 +1,25
1 1 {% extends "dev_conf.html" %}
2 2 {% load static %}
3 3 {% load bootstrap3 %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-menu-actions %}
7 <li><a href="{{ dev_conf.get_absolute_url_log }}"><span class="glyphicon glyphicon-save-file" aria-hidden="true"></span> Get Log File</a></li>
7 <li><a href="{{ dev_conf.get_absolute_url_log }}"><span class="glyphicon glyphicon-save-file" aria-hidden="true"></span>
8 Get Log File</a></li>
8 9 {% endblock %}
9 10
10 11 {% block extra-content %}
11 12
12 13 <div class="clearfix"></div>
13 <h2>JARS filter: {{resolution}}</h2>
14 <hr>
15 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
16 {% include "jars_filter.html" %}
17 </div>
14 <h2>Filter: {{resolution}}</h2>
15 <br>
16 <table class="table table-bordered">
17 {% for key in filter_keys %}
18 <tr>
19 <th>{% get_verbose_field_name filter_obj key %}</th>
20 <td>{{filter|attr:key}}</td>
21 </tr>
22 {% endfor %}
23 </table>
18 24
19 {% endblock extra-content%}
25 {% endblock extra-content%} No newline at end of file
@@ -1,32 +1,40
1 1 {% extends "dev_conf_edit.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block content %}
7 7 <form class="form" method="post">
8 8 {% csrf_token %}
9 9 {% bootstrap_form form layout='horizontal' size='medium' %}
10 10 <div style="clear: both;"></div>
11 <h2>JARS filter</h2>
12 <hr>
13 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
14 {% include "jars_filter_edit.html" %}
11 <h2>Filter <small>{{filter_name}}</small></h2>
12 <br>
13 {% bootstrap_form filter_form layout='horizontal' size='medium' %}
14 <div style="clear: both;"></div>
15 <br>
16 <div class="pull-right">
17 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
18 <button type="submit" class="btn btn-primary">{{button}}</button>
15 19 </div>
20
16 21 <div style="clear: both;"></div>
17 22 <br>
18 23 </form>
19 24 {% endblock %}
20 25
21
22 26 {% block extra-js%}
23 27 <script src="{% static 'js/jars.js' %}"></script>
24
28 <script src="{% static 'js/filters.js' %}"></script>
25 29 <script type="text/javascript">
26 30
27 $("#bt_cancel").click(function() {
31 $("#bt_cancel").click(function () {
28 32 document.location = "{% url 'url_jars_conf' id_dev %}";
29 });
33 });
34
35 $("#id_filter_template").change(function () {
36 document.location = "{% url 'url_change_jars_filter' id_dev %}" + $("#id_filter_template").val();
37 });
30 38
31 39 </script>
32 {% endblock %}
40 {% endblock %} No newline at end of file
@@ -1,240 +1,194
1 1 from django.shortcuts import render_to_response
2 2 from django.template import RequestContext
3 3 from django.shortcuts import redirect, render, get_object_or_404
4 4 from django.contrib import messages
5 5 from django.http import HttpResponse
6 6
7 7 from apps.main.models import Device
8 8 from apps.main.views import sidebar
9 9
10 from .models import JARSConfiguration, JARSfilter
11 from .forms import JARSConfigurationForm, JARSfilterForm, JARSImportForm
10 from .models import JARSConfiguration, JARSFilter
11 from .forms import JARSConfigurationForm, JARSFilterForm, JARSImportForm
12 12
13 13 import json
14 14 # Create your views here.
15 15
16 16 def jars_conf(request, id_conf):
17 17
18 18 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
19 19
20 filter_parms = eval(conf.filter_parms)
21 if filter_parms.__class__.__name__=='str':
22 filter_parms = eval(filter_parms)
20 filter_parms = json.loads(conf.filter_parms)
23 21
24 22 kwargs = {}
25 23 kwargs['filter'] = filter_parms
26 kwargs['filter_keys'] = ['clock', 'mult', 'fch', 'fch_decimal',
27 'filter_fir', 'filter_2', 'filter_5']
24 kwargs['filter_obj'] = JARSFilter.objects.get(pk=1)
25 kwargs['filter_keys'] = ['clock', 'multiplier', 'frequency', 'f_decimal',
26 'cic_2', 'scale_cic_2', 'cic_5', 'scale_cic_5', 'fir',
27 'scale_fir', 'number_taps', 'taps']
28 28
29 filter_resolution=conf.filter_resolution()
29 filter_resolution = conf.filter_resolution()
30 30 kwargs['resolution'] = '{} (MHz)'.format(filter_resolution)
31 31 if filter_resolution < 1:
32 32 kwargs['resolution'] = '{} (kHz)'.format(filter_resolution*1000)
33 33
34 34 kwargs['status'] = conf.device.get_status_display()
35
36
37 35 kwargs['dev_conf'] = conf
38 kwargs['dev_conf_keys'] = ['name',
39 'cards_number', 'channels_number', 'channels',
36 kwargs['dev_conf_keys'] = ['cards_number', 'channels_number', 'channels',
40 37 'ftp_interval', 'data_type','acq_profiles',
41 38 'profiles_block', 'raw_data_blocks', 'ftp_interval',
42 39 'cohe_integr_str', 'cohe_integr', 'decode_data', 'post_coh_int',
43 40 'incohe_integr', 'fftpoints', 'spectral_number',
44 41 'spectral', 'create_directory', 'include_expname',
45 42 'save_ch_dc', 'save_data']
46 43
47 44 if conf.exp_type == 0:
48 45 for field in ['incohe_integr','fftpoints','spectral_number', 'spectral', 'save_ch_dc']:
49 46 kwargs['dev_conf_keys'].remove(field)
50 47
51 48 if conf.decode_data == 0:
52 49 kwargs['dev_conf_keys'].remove('decode_data')
53 50 kwargs['dev_conf_keys'].remove('post_coh_int')
54 51
55 52 kwargs['title'] = 'JARS Configuration'
56 53 kwargs['suptitle'] = 'Details'
57 54
58 kwargs['button'] = 'Edit Configuration'
59
60 #kwargs['no_play'] = True
61
62 #kwargs['only_stop'] = True
63
64 55 ###### SIDEBAR ######
65 56 kwargs.update(sidebar(conf=conf))
66 57
67 58 return render(request, 'jars_conf.html', kwargs)
68 59
69 60 def jars_conf_edit(request, id_conf):
70 61
71 62 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
72 63
73 filter_parms = eval(conf.filter_parms)
74 if filter_parms.__class__.__name__=='str':
75 filter_parms = eval(filter_parms)
76
64 filter_parms = json.loads(conf.filter_parms)
65
77 66 if request.method=='GET':
78 67 form = JARSConfigurationForm(instance=conf)
79 filter_form = JARSfilterForm(initial=filter_parms)
68 filter_form = JARSFilterForm(initial=filter_parms)
80 69
81 70 if request.method=='POST':
82 71 form = JARSConfigurationForm(request.POST, instance=conf)
83 filter_form = JARSfilterForm(request.POST)
72 filter_form = JARSFilterForm(request.POST)
84 73
85 74 if filter_form.is_valid():
86 jars_filter = filter_form.cleaned_data
87 try:
88 jars_filter.pop('name')
89 except:
90 pass
75 jars_filter = filter_form.cleaned_data
76 jars_filter['id'] = request.POST['filter_template']
77 else:
78 messages.error(request, filter_form.errors)
91 79
92 80 if form.is_valid():
93 81 conf = form.save(commit=False)
94 82 conf.filter_parms = json.dumps(jars_filter)
95 83 conf.save()
96 84 return redirect('url_jars_conf', id_conf=conf.id)
97 85
98 86 kwargs = {}
99 87
100 88 kwargs['id_dev'] = conf.id
101 89 kwargs['form'] = form
102 90 kwargs['filter_form'] = filter_form
91 kwargs['filter_name'] = JARSFilter.objects.get(pk=filter_parms['id']).name
103 92 kwargs['title'] = 'Device Configuration'
104 93 kwargs['suptitle'] = 'Edit'
105 94 kwargs['button'] = 'Save'
106 95
107 96 return render(request, 'jars_conf_edit.html', kwargs)
108 97
109 98 def import_file(request, conf_id):
110 99
111 100 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
112 101 if request.method=='POST':
113 102 form = JARSImportForm(request.POST, request.FILES)
114 103 if form.is_valid():
115 104 try:
116 105 data = conf.import_from_file(request.FILES['file_name'])
117 106 conf.dict_to_parms(data)
118 107 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
119 108 return redirect(conf.get_absolute_url_edit())
120 109
121 110 except Exception as e:
122 111 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
123 112 else:
124 113 messages.warning(request, 'Your current configuration will be replaced')
125 114 form = JARSImportForm()
126 115
127 116 kwargs = {}
128 117 kwargs['form'] = form
129 118 kwargs['title'] = 'JARS Configuration'
130 119 kwargs['suptitle'] = 'Import file'
131 120 kwargs['button'] = 'Upload'
132 121 kwargs['previous'] = conf.get_absolute_url()
133 122
134 123 return render(request, 'jars_import.html', kwargs)
135 124
136 125 def read_conf(request, conf_id):
137 126
138 127 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
139 128 #filter = get_object_or_404(JARSfilter, pk=filter_id)
140 129
141 130 if request.method=='GET':
142 131
143 132 parms = conf.read_device()
144 133 conf.status_device()
145 134
146 135 if not parms:
147 136 messages.error(request, conf.message)
148 137 return redirect(conf.get_absolute_url())
149 138
150 139 form = JARSConfigurationForm(initial=parms, instance=conf)
151 140
152 141 if request.method=='POST':
153 142 form = JARSConfigurationForm(request.POST, instance=conf)
154 143
155 144 if form.is_valid():
156 145 form.save()
157 146 return redirect(conf.get_absolute_url())
158 147
159 148 messages.error(request, "Parameters could not be saved")
160 149
161 150 kwargs = {}
162 151 kwargs['id_dev'] = conf.id
163 152 kwargs['filter_id'] = conf.filter.id
164 153 kwargs['form'] = form
165 154 kwargs['title'] = 'Device Configuration'
166 155 kwargs['suptitle'] = 'Parameters read from device'
167 156 kwargs['button'] = 'Save'
168 157
169 158 ###### SIDEBAR ######
170 159 kwargs.update(sidebar(conf=conf))
171 160
172 161 return render(request, 'jars_conf_edit.html', kwargs)
173 162
174
175
176 def change_filter(request, conf_id, filter_id=None):
163 def change_filter(request, conf_id, filter_id):
177 164
178 165 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
166 filter = get_object_or_404(JARSFilter, pk=filter_id)
167 conf.filter_parms = json.dumps(filter.jsonify())
168 conf.save()
179 169
180 if filter_id:
181 if filter_id.__class__.__name__ not in ['int', 'float']:
182 filter_id = eval(filter_id)
183
184 if filter_id == 0:
185 return redirect('url_change_jars_filter', conf_id=conf.id)
186
187 if request.method=='GET':
188 if not filter_id:
189 form = JARSfilterForm(initial={'filter_id': 0})
190 else:
191 form = JARSfilterForm(initial={'filter_id': filter_id})
192
193 if request.method=='POST':
194 form = JARSfilterForm(request.POST)
195 if form.is_valid():
196 jars_filter = form.cleaned_data
197 try:
198 jars_filter.pop('name')
199 except:
200 pass
201 conf.filter_parms = json.dumps(jars_filter)
202 conf.save()
203 return redirect('url_edit_jars_conf', id_conf=conf.id)
204 else:
205 messages.error(request, "Select a Filter Template")
206 return redirect('url_change_jars_filter', conf_id=conf.id)
207
208 kwargs = {}
209 kwargs['title'] = 'JARS Configuration'
210 kwargs['suptitle'] = 'Change Filter'
211 kwargs['form'] = form
212 kwargs['button'] = 'Change'
213 kwargs['conf_id'] = conf.id
214 kwargs['filter_id'] = filter_id
215 return render(request, 'change_jars_filter.html', kwargs)
216
170 return redirect('url_edit_jars_conf', id_conf=conf.id)
217 171
218 172 def get_log(request, conf_id):
219 173
220 174 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
221 175 response = conf.get_log()
222 176
223 177 if not response:
224 178 message = conf.message
225 179 messages.error(request, message)
226 180 return redirect('url_jars_conf', id_conf=conf.id)
227 181
228 182 try:
229 183 message = response.json()['message']
230 184 messages.error(request, message)
231 185 return redirect('url_jars_conf', id_conf=conf.id)
232 186 except Exception as e:
233 187 message = 'Restarting Report.txt has been downloaded successfully.'
234 188
235 189 content = response
236 190 filename = 'Log_%s_%s.txt' %(conf.experiment.name, conf.experiment.id)
237 191 response = HttpResponse(content,content_type='text/plain')
238 192 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
239 193
240 194 return response
@@ -1,168 +1,165
1 1
2 2 import ast
3 3 import json
4 4 from itertools import chain
5 5
6 6 from django import forms
7 7 from django.utils.safestring import mark_safe
8 8 from django.utils.html import conditional_escape
9 9
10 10
11 11 class SpectralWidget(forms.widgets.TextInput):
12 12
13 13 def render(self, label, value, attrs=None):
14 14
15 15 readonly = 'readonly' if attrs.get('readonly', False) else ''
16 16 name = attrs.get('name', label)
17 print 'ESTO!'
18 print value
19 17 if value == None:
20 18 value = '[0, 0],'
21 print readonly
22 19 if '[' in value:
23 20 if value[len(value)-1] == ",":
24 21 value = ast.literal_eval(value)
25 22 else:
26 23 value = value + ","
27 24 value = ast.literal_eval(value)
28 25
29 26 codes = value
30 27 if not isinstance(value, list):
31 28 text=''
32 29 #lista = []
33 30 #if len(value) > 1:
34 31 for val in value:
35 32 text = text+str(val)+','
36 33 #lista.append(val)
37 34 codes=text
38 35 else:
39 36 codes=''
40 37
41 38 html = '''<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>
42 39 <input type="text" class="col-md-1 col-no-padding" id="num1" value=0>
43 40 <input type="text" class="col-md-1 col-no-padding" id="num2" value=0>
44 41 <button type="button" class="button" id="add_spectral_button"> Add </button>
45 42 <button type="button" class="button" id="delete_spectral_button"> Delete </button>
46 43 <button type="button" class="button pull-right" id="cross_spectral_button"> Cross </button>
47 44 <button type="button" class="button pull-right" id="self_spectral_button"> Self </button>
48 45 <button type="button" class="button pull-right" id="all_spectral_button"> All </button>
49 46 '''.format(readonly, label, name, codes)
50 47
51 48 script = '''
52 49 <script type="text/javascript">
53 50 $(document).ready(function () {{
54 51
55 52 var spectral_number1 = $("#num1").val();
56 53 var spectral_number2 = $("#num2").val();
57 54
58 55
59 56 $("#all_spectral_button").click(function(){{
60 57 var sequence1 = selfSpectral()
61 58 var sequence2 = crossSpectral()
62 59 $("#id_spectral").val(sequence1+sequence2)
63 60 updateSpectralNumber()
64 61 }});
65 62
66 63
67 64 $("#add_spectral_button").click(function(){{
68 65 var spectral_comb = $("#id_spectral").val();
69 66 var spectral_number1 = $("#num1").val();
70 67 var spectral_number2 = $("#num2").val();
71 68 var str = spectral_number1+", "+spectral_number2;
72 69 //not to duplicate
73 70 var n = spectral_comb.search(str);
74 71 if (n==-1){
75 72 $("#id_spectral").val(spectral_comb+"["+$("#num1").val()+", "+$("#num2").val()+"],")
76 73 }
77 74 updateSpectralNumber()
78 75 }});
79 76
80 77
81 78 $("#self_spectral_button").click(function(){{
82 79 var sequence = selfSpectral()
83 80 $("#id_spectral").val(sequence)
84 81
85 82 updateSpectralNumber()
86 83 }});
87 84
88 85 $("#cross_spectral_button").click(function(){{
89 86 var sequence = crossSpectral()
90 87 $("#id_spectral").val(sequence)
91 88
92 89 updateSpectralNumber()
93 90 }});
94 91
95 92
96 93 function selfSpectral() {
97 94 var channels = $("#id_channels").val();
98 95 var n = (channels.length)-1;
99 96 var num = parseInt(channels[n]);
100 97 sequence = ""
101 98 for (i = 0; i < num; i++) {
102 99 sequence = sequence + "[" + i.toString() + ", " + i.toString() + "],"
103 100 }
104 101 return sequence
105 102 }
106 103
107 104
108 105 function crossSpectral() {
109 106 var channels = $("#id_channels").val();
110 107 var n = (channels.length)-1;
111 108 var num = parseInt(channels[n]);
112 109 sequence = ""
113 110 for (i = 0; i < num; i++) {
114 111 for (j = i+1; j < num; j++) {
115 112 sequence = sequence + "[" + i.toString() + ", " + j.toString() + "],"
116 113 }
117 114 }
118 115 return sequence
119 116 }
120 117
121 118
122 119 function updateSpectralNumber(){
123 120 var spectral_comb = $("#id_spectral").val();
124 121 var num = spectral_comb.length;
125 122 var cont = 0
126 123 for (i = 0; i < num; i++) {
127 124 if (spectral_comb[i] == "]"){
128 125 cont = cont + 1
129 126 }
130 127 }
131 128 $("#id_spectral_number").val(cont)
132 129 }
133 130
134 131
135 132 $("#delete_spectral_button").click(function(){{
136 133 var spectral_comb = $("#id_spectral").val();
137 134 var spectral_number1 = $("#num1").val();
138 135 var spectral_number2 = $("#num2").val();
139 136 var str = spectral_number1+", "+spectral_number2;
140 137 var n = spectral_comb.search(str);
141 138 if (n==-1){
142 139
143 140 }
144 141 else {
145 142 n= spectral_comb.length;
146 143 if (n<8){
147 144 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
148 145 var txt = spectral_comb.replace(tuple,'');
149 146 }
150 147 else {
151 148 var tuple = ",["+$("#num1").val()+", "+$("#num2").val()+"]"
152 149 var txt = spectral_comb.replace(tuple,'');
153 150 }
154 151 $("#id_spectral").val(txt)
155 152
156 153 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
157 154 var txt = spectral_comb.replace(tuple,'');
158 155 $("#id_spectral").val(txt)
159 156 }
160 157 updateSpectralNumber()
161 158 }});
162 159
163 160
164 161 }});
165 162 </script>
166 163 '''
167 164
168 165 return mark_safe(html+script)
@@ -1,13 +1,122
1 1 [
2 {"fields": {"name": "JRO", "description": ""}, "model": "main.location", "pk": 1},
3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
5 {"fields": {"name": "JULIA", "description": ""}, "model": "main.location", "pk": 4},
6 {"fields": {"name": "CLAIRE", "description": ""}, "model": "main.location", "pk": 4},
7 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
8 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
9 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
10 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4},
11 {"fields": {"name": "abs", "description": ""}, "model": "main.devicetype", "pk": 5},
12 {"fields": {"password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=", "last_login": null, "is_superuser": true, "username": "admin", "first_name": "", "last_name": "", "email": "admin@admin.com", "is_staff": true, "is_active": true, "date_joined": "2017-01-12T16:10:24.383", "groups": [], "user_permissions": []}, "model": "auth.user", "pk": 1}
13 ]
2 {
3 "fields": {
4 "name": "JRO",
5 "description": ""
6 },
7 "model": "main.location",
8 "pk": 1
9 },
10 {
11 "fields": {
12 "name": "JASMET",
13 "description": ""
14 },
15 "model": "main.location",
16 "pk": 2
17 },
18 {
19 "fields": {
20 "name": "SOUSY",
21 "description": ""
22 },
23 "model": "main.location",
24 "pk": 3
25 },
26 {
27 "fields": {
28 "name": "JULIA",
29 "description": ""
30 },
31 "model": "main.location",
32 "pk": 4
33 },
34 {
35 "fields": {
36 "name": "CLAIRE",
37 "description": ""
38 },
39 "model": "main.location",
40 "pk": 5
41 },
42 {
43 "fields": {
44 "name": "IDI",
45 "description": ""
46 },
47 "model": "main.location",
48 "pk": 6
49 },
50 {
51 "fields": {
52 "name": "rc",
53 "description": ""
54 },
55 "model": "main.devicetype",
56 "pk": 1
57 },
58 {
59 "fields": {
60 "name": "dds",
61 "description": ""
62 },
63 "model": "main.devicetype",
64 "pk": 2
65 },
66 {
67 "fields": {
68 "name": "cgs",
69 "description": ""
70 },
71 "model": "main.devicetype",
72 "pk": 3
73 },
74 {
75 "fields": {
76 "name": "jars",
77 "description": ""
78 },
79 "model": "main.devicetype",
80 "pk": 4
81 },
82 {
83 "fields": {
84 "name": "abs",
85 "description": ""
86 },
87 "model": "main.devicetype",
88 "pk": 5
89 },
90 {
91 "fields": {
92 "name": "Operator"
93 },
94 "model": "auth.group",
95 "pk": 1
96 },
97 {
98 "fields": {
99 "name": "Developer"
100 },
101 "model": "auth.group",
102 "pk": 2
103 },
104 {
105 "fields": {
106 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
107 "last_login": null,
108 "is_superuser": true,
109 "username": "admin",
110 "first_name": "Administrador",
111 "last_name": "IDI",
112 "email": "admin@admin.com",
113 "is_staff": true,
114 "is_active": true,
115 "date_joined": "2017-01-12T16:10:24.383",
116 "groups": [],
117 "user_permissions": []
118 },
119 "model": "auth.user",
120 "pk": 1
121 }
122 ] No newline at end of file
@@ -1,202 +1,202
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3 3 from apps.main.models import Device, Experiment, Campaign, Location, Configuration
4 4 from django.template.defaultfilters import default
5 5
6 6 FILE_FORMAT = (
7 7 ('json', 'json'),
8 8 )
9 9
10 10 DDS_FILE_FORMAT = (
11 11 ('json', 'json'),
12 12 ('text', 'dds')
13 13 )
14 14
15 15 RC_FILE_FORMAT = (
16 16 ('json', 'json'),
17 17 ('text', 'racp'),
18 18 ('binary', 'dat'),
19 19 )
20 20
21 21 JARS_FILE_FORMAT = (
22 22 ('json', 'json'),
23 23 ('racp', 'racp'),
24 24 ('text', 'jars'),
25 25 )
26 26
27 27 def add_empty_choice(choices, pos=0, label='-----'):
28 28 if len(choices)>0:
29 29 choices = list(choices)
30 30 choices.insert(0, (0, label))
31 31 return choices
32 32 else:
33 33 return [(0, label)]
34 34
35 35 class DatepickerWidget(forms.widgets.TextInput):
36 36 def render(self, name, value, attrs=None):
37 37 input_html = super(DatepickerWidget, self).render(name, value, attrs)
38 38 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
39 39 return mark_safe(html)
40 40
41 41 class DateRangepickerWidget(forms.widgets.TextInput):
42 42 def render(self, name, value, attrs=None):
43 43 start = attrs['start_date']
44 44 end = attrs['end_date']
45 45 html = '''<div class="col-md-6 input-group date" style="float:inherit">
46 46 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
47 47 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
48 48 </div>
49 49 <div class="col-md-6 input-group date" style="float:inherit">
50 50 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
51 51 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
52 52 </div>'''.format(start, end)
53 53 return mark_safe(html)
54 54
55 55 class TimepickerWidget(forms.widgets.TextInput):
56 56 def render(self, name, value, attrs=None):
57 57 input_html = super(TimepickerWidget, self).render(name, value, attrs)
58 58 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
59 59 return mark_safe(html)
60 60
61 61 class CampaignForm(forms.ModelForm):
62 62
63 63 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
64 64 queryset=Experiment.objects.filter(template=True),
65 65 required=False)
66 66
67 67 def __init__(self, *args, **kwargs):
68 68 super(CampaignForm, self).__init__(*args, **kwargs)
69 69 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
70 70 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
71 71 self.fields['description'].widget.attrs = {'rows': 2}
72 72
73 73 if self.instance.pk:
74 74 self.fields['experiments'].queryset |= self.instance.experiments.all()
75 75
76 76 class Meta:
77 77 model = Campaign
78 exclude = ['']
78 exclude = ['author']
79 79
80 80
81 81 class ExperimentForm(forms.ModelForm):
82 82
83 83 def __init__(self, *args, **kwargs):
84 84 super(ExperimentForm, self).__init__(*args, **kwargs)
85 85 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
86 86 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
87 87
88 def save(self):
89 exp = super(ExperimentForm, self).save()
88 def save(self, *args, **kwargs):
89 exp = super(ExperimentForm, self).save(*args, **kwargs)
90 90 exp.name = exp.name.replace(' ', '')
91 91 exp.save()
92 92 return exp
93 93
94 94 class Meta:
95 95 model = Experiment
96 exclude = ['task', 'status']
96 exclude = ['task', 'status', 'author', 'hash']
97 97
98 98 class LocationForm(forms.ModelForm):
99 99 class Meta:
100 100 model = Location
101 101 exclude = ['']
102 102
103 103 class DeviceForm(forms.ModelForm):
104 104 class Meta:
105 105 model = Device
106 106 exclude = ['status']
107 107
108 108 class ConfigurationForm(forms.ModelForm):
109 109
110 110 def __init__(self, *args, **kwargs):
111 111 super(ConfigurationForm, self).__init__(*args, **kwargs)
112 112
113 113 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
114 114 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
115 115
116 116 class Meta:
117 117 model = Configuration
118 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
118 exclude = ['type', 'created_date', 'programmed_date', 'parameters', 'author', 'hash']
119 119
120 120 class UploadFileForm(forms.Form):
121 121
122 122 file = forms.FileField()
123 123
124 124 class DownloadFileForm(forms.Form):
125 125
126 126 format = forms.ChoiceField(choices= ((0, 'json'),) )
127 127
128 128 def __init__(self, device_type, *args, **kwargs):
129 129
130 130 super(DownloadFileForm, self).__init__(*args, **kwargs)
131 131
132 132 self.fields['format'].choices = FILE_FORMAT
133 133
134 134 if device_type == 'dds':
135 135 self.fields['format'].choices = DDS_FILE_FORMAT
136 136
137 137 if device_type == 'rc':
138 138 self.fields['format'].choices = RC_FILE_FORMAT
139 139
140 140 if device_type == 'jars':
141 141 self.fields['format'].choices = JARS_FILE_FORMAT
142 142
143 143 class OperationForm(forms.Form):
144 144
145 145 campaign = forms.ChoiceField(label="Campaign")
146 146
147 147 def __init__(self, *args, **kwargs):
148 148
149 149 campaigns = kwargs.pop('campaigns')
150 150 super(OperationForm, self).__init__(*args, **kwargs)
151 151 self.fields['campaign'].label = 'Current Campaigns'
152 152 self.fields['campaign'].choices = add_empty_choice(campaigns.values_list('id', 'name'))
153 153
154 154
155 155 class OperationSearchForm(forms.Form):
156 156 # -----ALL Campaigns------
157 157 campaign = forms.ChoiceField(label="Campaign")
158 158
159 159 def __init__(self, *args, **kwargs):
160 160 super(OperationSearchForm, self).__init__(*args, **kwargs)
161 161 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
162 162
163 163
164 164 class NewForm(forms.Form):
165 165
166 166 create_from = forms.ChoiceField(choices=((0, '-----'),
167 167 (1, 'Empty (blank)'),
168 168 (2, 'Template')))
169 169 choose_template = forms.ChoiceField()
170 170
171 171 def __init__(self, *args, **kwargs):
172 172
173 173 template_choices = kwargs.pop('template_choices', [])
174 174 super(NewForm, self).__init__(*args, **kwargs)
175 175 self.fields['choose_template'].choices = add_empty_choice(template_choices)
176 176
177 177
178 178 class FilterForm(forms.Form):
179 179
180 180 def __init__(self, *args, **kwargs):
181 181 extra_fields = kwargs.pop('extra_fields', [])
182 182 super(FilterForm, self).__init__(*args, **kwargs)
183 183
184 184 for field in extra_fields:
185 185 if 'range_date' in field:
186 186 self.fields[field] = forms.CharField(required=False)
187 187 self.fields[field].widget = DateRangepickerWidget()
188 188 if 'initial' in kwargs:
189 189 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
190 190 'end_date':kwargs['initial'].get('end_date', '')}
191 elif field in ('template', 'historical'):
191 elif field in ('template', 'historical') or 'my ' in field:
192 192 self.fields[field] = forms.BooleanField(required=False)
193 193 else:
194 194 self.fields[field] = forms.CharField(required=False)
195 195
196 196 class ChangeIpForm(forms.Form):
197 197
198 198 ip_address = forms.GenericIPAddressField()
199 199 mask = forms.GenericIPAddressField(initial='255.255.255.0')
200 200 gateway = forms.GenericIPAddressField(initial='0.0.0.0')
201 201 dns = forms.GenericIPAddressField(initial='0.0.0.0')
202 202
@@ -1,761 +1,794
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.core.urlresolvers import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 19
19 20 from apps.main.utils import Params
20 21 from apps.rc.utils import RCFile
21 22 from apps.jars.utils import RacpFile
22 23 from devices.dds import api as dds_api
23 24 from devices.dds import data as dds_data
24 25
25 26
26 27 DEV_PORTS = {
27 28 'rc' : 2000,
28 29 'dds' : 2000,
29 30 'jars' : 2000,
30 31 'usrp' : 2000,
31 32 'cgs' : 8080,
32 33 'abs' : 8080
33 34 }
34 35
35 36 RADAR_STATES = (
36 37 (0, 'No connected'),
37 38 (1, 'Connected'),
38 39 (2, 'Configured'),
39 40 (3, 'Running'),
40 41 (4, 'Scheduled'),
41 42 )
42 43
43 44 EXPERIMENT_TYPE = (
44 45 (0, 'RAW_DATA'),
45 46 (1, 'PDATA'),
46 47 )
47 48
48 49 DECODE_TYPE = (
49 50 (0, 'None'),
50 51 (1, 'TimeDomain'),
51 52 (2, 'FreqDomain'),
52 53 (3, 'InvFreqDomain'),
53 54 )
54 55
55 56 DEV_STATES = (
56 57 (0, 'No connected'),
57 58 (1, 'Connected'),
58 59 (2, 'Configured'),
59 60 (3, 'Running'),
60 61 (4, 'Unknown'),
61 62 )
62 63
63 64 DEV_TYPES = (
64 65 ('', 'Select a device type'),
65 66 ('rc', 'Radar Controller'),
66 67 ('dds', 'Direct Digital Synthesizer'),
67 68 ('jars', 'Jicamarca Radar Acquisition System'),
68 69 ('usrp', 'Universal Software Radio Peripheral'),
69 70 ('cgs', 'Clock Generator System'),
70 71 ('abs', 'Automatic Beam Switching'),
71 72 )
72 73
73 74 EXP_STATES = (
74 75 (0,'Error'), #RED
75 76 (1,'Configured'), #BLUE
76 77 (2,'Running'), #GREEN
77 78 (3,'Scheduled'), #YELLOW
78 79 (4,'Not Configured'), #WHITE
79 80 )
80 81
81 82 CONF_TYPES = (
82 83 (0, 'Active'),
83 84 (1, 'Historical'),
84 85 )
85 86
86 87 class Location(models.Model):
87 88
88 89 name = models.CharField(max_length = 30)
89 90 description = models.TextField(blank=True, null=True)
90 91
91 92 class Meta:
92 93 db_table = 'db_location'
93 94
94 95 def __str__(self):
95 96 return u'%s' % self.name
96 97
97 98 def get_absolute_url(self):
98 99 return reverse('url_location', args=[str(self.id)])
99 100
100 101
101 102 class DeviceType(models.Model):
102 103
103 104 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
104 105 sequence = models.PositiveSmallIntegerField(default=1000)
105 106 description = models.TextField(blank=True, null=True)
106 107
107 108 class Meta:
108 109 db_table = 'db_device_types'
109 110
110 111 def __str__(self):
111 112 return u'%s' % self.get_name_display()
112 113
113 114 class Device(models.Model):
114 115
115 116 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
116 117 location = models.ForeignKey(Location, on_delete=models.CASCADE)
117
118 name = models.CharField(max_length=40, default='')
119 118 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
120 119 port_address = models.PositiveSmallIntegerField(default=2000)
121 120 description = models.TextField(blank=True, null=True)
122 121 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
123 122
124 123 class Meta:
125 124 db_table = 'db_devices'
126 125
127 126 def __str__(self):
128 return u'[{}]: {}'.format(self.device_type.name.upper(),
129 self.name)
127 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
128
129 return ret
130
131 @property
132 def name(self):
133 return str(self)
130 134
131 135 def get_status(self):
132 136 return self.status
133 137
134 138 @property
135 139 def status_color(self):
136 140 color = 'muted'
137 141 if self.status == 0:
138 142 color = "danger"
139 143 elif self.status == 1:
140 144 color = "warning"
141 145 elif self.status == 2:
142 146 color = "info"
143 147 elif self.status == 3:
144 148 color = "success"
145 149
146 150 return color
147 151
148 152 def url(self, path=None):
149 153
150 154 if path:
151 155 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
152 156 else:
153 157 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
154 158
155 159 def get_absolute_url(self):
156
157 160 return reverse('url_device', args=[str(self.id)])
158 161
162 def get_absolute_url_edit(self):
163 return reverse('url_edit_device', args=[str(self.id)])
164
165 def get_absolute_url_delete(self):
166 return reverse('url_delete_device', args=[str(self.id)])
167
159 168 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
160 169
161 170 if self.device_type.name=='dds':
162 171 try:
163 172 answer = dds_api.change_ip(ip = self.ip_address,
164 173 port = self.port_address,
165 174 new_ip = ip_address,
166 175 mask = mask,
167 176 gateway = gateway)
168 177 if answer[0]=='1':
169 178 self.message = '25|DDS - {}'.format(answer)
170 179 self.ip_address = ip_address
171 180 self.save()
172 181 else:
173 182 self.message = '30|DDS - {}'.format(answer)
174 183 return False
175 184 except Exception as e:
176 185 self.message = '40|{}'.format(str(e))
177 186 return False
178 187
179 188 elif self.device_type.name=='rc':
180 189 headers = {'content-type': "application/json",
181 190 'cache-control': "no-cache"}
182 191
183 192 ip = [int(x) for x in ip_address.split('.')]
184 193 dns = [int(x) for x in dns.split('.')]
185 194 gateway = [int(x) for x in gateway.split('.')]
186 195 subnet = [int(x) for x in mask.split('.')]
187 196
188 197 payload = {
189 198 "ip": ip,
190 199 "dns": dns,
191 200 "gateway": gateway,
192 201 "subnet": subnet
193 202 }
194 203
195 204 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
196 205 try:
197 206 answer = req.json()
198 207 if answer['changeip']=='ok':
199 208 self.message = '25|IP succesfully changed'
200 209 self.ip_address = ip_address
201 210 self.save()
202 211 else:
203 212 self.message = '30|An error ocuur when changing IP'
204 213 except Exception as e:
205 214 self.message = '40|{}'.format(str(e))
206 215 else:
207 216 self.message = 'Not implemented'
208 217 return False
209 218
210 219 return True
211 220
212 221
213 222 class Campaign(models.Model):
214 223
215 224 template = models.BooleanField(default=False)
216 225 name = models.CharField(max_length=60, unique=True)
217 226 start_date = models.DateTimeField(blank=True, null=True)
218 227 end_date = models.DateTimeField(blank=True, null=True)
219 tags = models.CharField(max_length=40)
228 tags = models.CharField(max_length=40, blank=True, null=True)
220 229 description = models.TextField(blank=True, null=True)
221 230 experiments = models.ManyToManyField('Experiment', blank=True)
222
231 author = models.ForeignKey(User, null=True, blank=True)
232
223 233 class Meta:
224 234 db_table = 'db_campaigns'
225 235 ordering = ('name',)
226 236
227 237 def __str__(self):
228 238 if self.template:
229 239 return u'{} (template)'.format(self.name)
230 240 else:
231 241 return u'{}'.format(self.name)
232 242
233 243 def jsonify(self):
234 244
235 245 data = {}
236 246
237 247 ignored = ('template')
238 248
239 249 for field in self._meta.fields:
240 250 if field.name in ignored:
241 251 continue
242 252 data[field.name] = field.value_from_object(self)
243 253
244 254 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
245 255 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
246 256
247 257 return data
248 258
249 259 def parms_to_dict(self):
250 260
251 261 params = Params({})
252 262 params.add(self.jsonify(), 'campaigns')
253 263
254 264 for exp in Experiment.objects.filter(campaign = self):
255 265 params.add(exp.jsonify(), 'experiments')
256 266 configurations = Configuration.objects.filter(experiment=exp, type=0)
257 267
258 268 for conf in configurations:
259 269 params.add(conf.jsonify(), 'configurations')
260 270 if conf.device.device_type.name=='rc':
261 271 for line in conf.get_lines():
262 272 params.add(line.jsonify(), 'lines')
263 273
264 274 return params.data
265 275
266 276 def dict_to_parms(self, parms, CONF_MODELS):
267 277
268 278 experiments = Experiment.objects.filter(campaign = self)
269 279
270 280 if experiments:
271 281 for experiment in experiments:
272 282 experiment.delete()
273 283
274 284 for id_exp in parms['experiments']['allIds']:
275 285 exp_parms = parms['experiments']['byId'][id_exp]
276 286 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
277 287 exp = Experiment(name='{}'.format(dum))
278 288 exp.save()
279 289 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
280 290 self.experiments.add(exp)
281 291
282 292 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
283 293
284 294 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
285 295 self.start_date = camp_parms['start_date']
286 296 self.end_date = camp_parms['end_date']
287 297 self.tags = camp_parms['tags']
288 298 self.save()
289 299
290 300 return self
291 301
292 302 def get_experiments_by_radar(self, radar=None):
293 303
294 304 ret = []
295 305 if radar:
296 306 locations = Location.objects.filter(pk=radar)
297 307 else:
298 308 locations = set([e.location for e in self.experiments.all()])
299 309
300 310 for loc in locations:
301 311 dum = {}
302 312 dum['name'] = loc.name
303 313 dum['id'] = loc.pk
304 314 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
305 315 ret.append(dum)
306 316
307 317 return ret
308 318
309 319 def get_absolute_url(self):
310 320 return reverse('url_campaign', args=[str(self.id)])
311 321
312 322 def get_absolute_url_edit(self):
313 323 return reverse('url_edit_campaign', args=[str(self.id)])
314 324
325 def get_absolute_url_delete(self):
326 return reverse('url_delete_campaign', args=[str(self.id)])
327
315 328 def get_absolute_url_export(self):
316 329 return reverse('url_export_campaign', args=[str(self.id)])
317 330
318 331 def get_absolute_url_import(self):
319 332 return reverse('url_import_campaign', args=[str(self.id)])
320 333
321 334
322
323 335 class RunningExperiment(models.Model):
324 336 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
325 337 running_experiment = models.ManyToManyField('Experiment', blank = True)
326 338 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
327 339
328 340
329 341 class Experiment(models.Model):
330 342
331 343 template = models.BooleanField(default=False)
332 344 name = models.CharField(max_length=40, default='', unique=True)
333 345 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
334 346 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
335 347 start_time = models.TimeField(default='00:00:00')
336 348 end_time = models.TimeField(default='23:59:59')
337 349 task = models.CharField(max_length=36, default='', blank=True, null=True)
338 350 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
351 author = models.ForeignKey(User, null=True, blank=True)
352 hash = models.CharField(default='', max_length=64, null=True, blank=True)
339 353
340 354 class Meta:
341 355 db_table = 'db_experiments'
342 356 ordering = ('template', 'name')
343 357
344 358 def __str__(self):
345 359 if self.template:
346 return u'%s (template)' % (self.name)
360 return u'%s (template)' % (self.name[:8])
347 361 else:
348 return u'%s' % (self.name)
362 return u'%s' % (self.name[:10])
349 363
350 364 def jsonify(self):
351 365
352 366 data = {}
353 367
354 368 ignored = ('template')
355 369
356 370 for field in self._meta.fields:
357 371 if field.name in ignored:
358 372 continue
359 373 data[field.name] = field.value_from_object(self)
360 374
361 375 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
362 376 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
363 377 data['location'] = self.location.name
364 378 data['configurations'] = ['{}'.format(conf.pk) for
365 379 conf in Configuration.objects.filter(experiment=self, type=0)]
366 380
367 381 return data
368 382
369 383 @property
370 384 def radar_system(self):
371 385 return self.location
372 386
373 387 def clone(self, **kwargs):
374 388
375 389 confs = Configuration.objects.filter(experiment=self, type=0)
376 390 self.pk = None
377 self.name = '{} [{:%Y-%m-%d}]'.format(self.name, datetime.now())
391 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
378 392 for attr, value in kwargs.items():
379 393 setattr(self, attr, value)
380 394
381 395 self.save()
382 396
383 397 for conf in confs:
384 398 conf.clone(experiment=self, template=False)
385 399
386 400 return self
387 401
388 402 def start(self):
389 403 '''
390 404 Configure and start experiments's devices
391 405 ABS-CGS-DDS-RC-JARS
392 406 '''
393 407
394 408 result = 2
395 409 confs = []
396 410 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
397 411 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
398 412 if rc_mix:
399 413 for conf in allconfs:
400 414 if conf.device.device_type.name == 'rc' and not conf.mix:
401 415 continue
402 416 confs.append(conf)
403 417 else:
404 418 confs = allconfs
405 419 #Only Configured Devices.
406 420 for conf in confs:
407 421 if conf.device.status in (0, 4):
408 422 result = 0
409 423 return result
410 424 for conf in confs:
411 425 conf.stop_device()
412 426 conf.write_device()
413 427 conf.start_device()
414 428 time.sleep(1)
415 429
416 430 return result
417 431
418 432
419 433 def stop(self):
420 434 '''
421 435 Stop experiments's devices
422 436 DDS-JARS-RC-CGS-ABS
423 437 '''
424 438
425 439 result = 1
426 440
427 441 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
428 442 confs=confs.exclude(device__device_type__name='cgs')
429 443 for conf in confs:
430 444 if conf.device.status in (0, 4):
431 445 result = 0
432 446 continue
433 447 conf.stop_device()
434 448
435 449 return result
436 450
437 451
438 452 def get_status(self):
439 453
440 454 if self.status == 3:
441 455 return
442 456
443 457 confs = Configuration.objects.filter(experiment=self, type=0)
444 458
445 459 for conf in confs:
446 460 conf.status_device()
447 461
448 462 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
449 463
450 464 if total==2*confs.count():
451 465 status = 1
452 466 elif total == 3*confs.count():
453 467 status = 2
454 468 else:
455 469 status = 0
456 470
457 471 self.status = status
458 472 self.save()
459 473
460 474 def status_color(self):
461 475 color = 'muted'
462 476 if self.status == 0:
463 477 color = "danger"
464 478 elif self.status == 1:
465 479 color = "info"
466 480 elif self.status == 2:
467 481 color = "success"
468 482 elif self.status == 3:
469 483 color = "warning"
470 484
471 485 return color
472 486
473 487 def parms_to_dict(self):
474 488
475 489 params = Params({})
476 490 params.add(self.jsonify(), 'experiments')
477 491
478 492 configurations = Configuration.objects.filter(experiment=self, type=0)
479 493
480 494 for conf in configurations:
481 495 params.add(conf.jsonify(), 'configurations')
482 496 if conf.device.device_type.name=='rc':
483 497 for line in conf.get_lines():
484 498 params.add(line.jsonify(), 'lines')
485 499
486 500 return params.data
487 501
488 502 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
489 503
490 504 configurations = Configuration.objects.filter(experiment=self)
491 505
492 506 if id_exp is not None:
493 507 exp_parms = parms['experiments']['byId'][id_exp]
494 508 else:
495 509 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
496 510
497 511 if configurations:
498 512 for configuration in configurations:
499 513 configuration.delete()
500 514
501 515 for id_conf in exp_parms['configurations']:
502 516 conf_parms = parms['configurations']['byId'][id_conf]
503 517 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
504 518 model = CONF_MODELS[conf_parms['device_type']]
505 519 conf = model(
506 520 experiment = self,
507 521 device = device,
508 522 )
509 523 conf.dict_to_parms(parms, id=id_conf)
510 524
511 525
512 526 location, created = Location.objects.get_or_create(name=exp_parms['location'])
513 527 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
514 528 self.location = location
515 529 self.start_time = exp_parms['start_time']
516 530 self.end_time = exp_parms['end_time']
517 531 self.save()
518 532
519 533 return self
520 534
521 535 def get_absolute_url(self):
522 536 return reverse('url_experiment', args=[str(self.id)])
523 537
524 538 def get_absolute_url_edit(self):
525 539 return reverse('url_edit_experiment', args=[str(self.id)])
526 540
541 def get_absolute_url_delete(self):
542 return reverse('url_delete_experiment', args=[str(self.id)])
543
527 544 def get_absolute_url_import(self):
528 545 return reverse('url_import_experiment', args=[str(self.id)])
529 546
530 547 def get_absolute_url_export(self):
531 548 return reverse('url_export_experiment', args=[str(self.id)])
532 549
533 550 def get_absolute_url_start(self):
534 551 return reverse('url_start_experiment', args=[str(self.id)])
535 552
536 553 def get_absolute_url_stop(self):
537 554 return reverse('url_stop_experiment', args=[str(self.id)])
538 555
539 556
540 557 class Configuration(PolymorphicModel):
541 558
542 559 template = models.BooleanField(default=False)
543 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
560 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
561 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
544 562 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
545 563 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
546 564 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
547 565 created_date = models.DateTimeField(auto_now_add=True)
548 566 programmed_date = models.DateTimeField(auto_now=True)
549 567 parameters = models.TextField(default='{}')
568 author = models.ForeignKey(User, null=True, blank=True)
569 hash = models.CharField(default='', max_length=64, null=True, blank=True)
550 570 message = ""
551 571
552 572 class Meta:
553 573 db_table = 'db_configurations'
574 ordering = ('device__device_type__name',)
554 575
555 576 def __str__(self):
556 577
557 device = '{}:'.format(self.device.device_type.name.upper())
578 ret = u'{} '.format(self.device.device_type.name.upper())
558 579
559 580 if 'mix' in [f.name for f in self._meta.get_fields()]:
560 581 if self.mix:
561 device = '{} MIXED:'.format(self.device.device_type.name.upper())
582 ret = '{} MIX '.format(self.device.device_type.name.upper())
583
584 if 'label' in [f.name for f in self._meta.get_fields()]:
585 ret += '{}'.format(self.label[:8])
562 586
587 #ret += '[ {} ]'.format(self.device.location.name)
563 588 if self.template:
564 return u'{} {} (template)'.format(device, self.name)
565 else:
566 return u'{} {}'.format(device, self.name)
589 ret += ' (template)'
590
591 return ret
592
593 @property
594 def name(self):
595
596 return str(self)
567 597
568 598 def jsonify(self):
569 599
570 600 data = {}
571 601
572 602 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
573 603 'created_date', 'programmed_date', 'template', 'device',
574 604 'experiment')
575 605
576 606 for field in self._meta.fields:
577 607 if field.name in ignored:
578 608 continue
579 609 data[field.name] = field.value_from_object(self)
580 610
581 611 data['device_type'] = self.device.device_type.name
582 612
583 613 if self.device.device_type.name == 'rc':
584 614 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
585 615 data['delays'] = self.get_delays()
586 616 data['pulses'] = self.get_pulses()
587 617
588 618 elif self.device.device_type.name == 'jars':
589 619 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
590 620
591 621 elif self.device.device_type.name == 'dds':
592 622 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
593 623 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
594 624 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
595 625 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
596 626
597 627 return data
598 628
599 629 def clone(self, **kwargs):
600 630
601 631 self.pk = None
602 632 self.id = None
603 633 for attr, value in kwargs.items():
604 634 setattr(self, attr, value)
605 635
606 636 self.save()
607 637
608 638 return self
609 639
610 640 def parms_to_dict(self):
611 641
612 642 params = Params({})
613 643 params.add(self.jsonify(), 'configurations')
614 644
615 645 if self.device.device_type.name=='rc':
616 646 for line in self.get_lines():
617 647 params.add(line.jsonify(), 'lines')
618 648
619 649 return params.data
620 650
621 651 def parms_to_text(self):
622 652
623 653 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
624 654
625 655
626 656 def parms_to_binary(self):
627 657
628 658 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
629 659
630 660
631 661 def dict_to_parms(self, parameters, id=None):
632 662
633 663 params = Params(parameters)
634 664
635 665 if id:
636 666 data = params.get_conf(id_conf=id)
637 667 else:
638 668 data = params.get_conf(dtype=self.device.device_type.name)
639 669
640 670 if data['device_type']=='rc':
641 671 self.clean_lines()
642 672 lines = data.pop('lines', None)
643 673 for line_id in lines:
644 674 pass
645 675
646 676 for key, value in data.items():
647 677 if key not in ('id', 'device_type'):
648 678 setattr(self, key, value)
649 679
650 680 self.save()
651 681
652 682
653 683 def export_to_file(self, format="json"):
654 684
655 685 content_type = ''
656 686
657 687 if format == 'racp':
658 688 content_type = 'text/plain'
659 689 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
660 690 content = self.parms_to_text(file_format = 'racp')
661 691
662 692 if format == 'text':
663 693 content_type = 'text/plain'
664 694 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
665 695 content = self.parms_to_text()
666 696
667 697 if format == 'binary':
668 698 content_type = 'application/octet-stream'
669 699 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
670 700 content = self.parms_to_binary()
671 701
672 702 if not content_type:
673 703 content_type = 'application/json'
674 704 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
675 705 content = json.dumps(self.parms_to_dict(), indent=2)
676 706
677 707 fields = {'content_type':content_type,
678 708 'filename':filename,
679 709 'content':content
680 710 }
681 711
682 712 return fields
683 713
684 714 def import_from_file(self, fp):
685 715
686 716 parms = {}
687 717
688 718 path, ext = os.path.splitext(fp.name)
689 719
690 720 if ext == '.json':
691 721 parms = json.load(fp)
692 722
693 723 if ext == '.dds':
694 724 lines = fp.readlines()
695 725 parms = dds_data.text_to_dict(lines)
696 726
697 727 if ext == '.racp':
698 728 if self.device.device_type.name == 'jars':
699 729 parms = RacpFile(fp).to_dict()
700 730 parms['filter_parms'] = json.loads(self.filter_parms)
701 731 return parms
702 732 parms = RCFile(fp).to_dict()
703 733
704 734 return parms
705 735
706 736 def status_device(self):
707 737
708 738 self.message = 'Function not implemented'
709 739 return False
710 740
711 741
712 742 def stop_device(self):
713 743
714 744 self.message = 'Function not implemented'
715 745 return False
716 746
717 747
718 748 def start_device(self):
719 749
720 750 self.message = 'Function not implemented'
721 751 return False
722 752
723 753
724 754 def write_device(self, parms):
725 755
726 756 self.message = 'Function not implemented'
727 757 return False
728 758
729 759
730 760 def read_device(self):
731 761
732 762 self.message = 'Function not implemented'
733 763 return False
734 764
735 765
736 766 def get_absolute_url(self):
737 767 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
738 768
739 769 def get_absolute_url_edit(self):
740 770 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
741 771
772 def get_absolute_url_delete(self):
773 return reverse('url_delete_dev_conf', args=[str(self.id)])
774
742 775 def get_absolute_url_import(self):
743 776 return reverse('url_import_dev_conf', args=[str(self.id)])
744 777
745 778 def get_absolute_url_export(self):
746 779 return reverse('url_export_dev_conf', args=[str(self.id)])
747 780
748 781 def get_absolute_url_write(self):
749 782 return reverse('url_write_dev_conf', args=[str(self.id)])
750 783
751 784 def get_absolute_url_read(self):
752 785 return reverse('url_read_dev_conf', args=[str(self.id)])
753 786
754 787 def get_absolute_url_start(self):
755 788 return reverse('url_start_dev_conf', args=[str(self.id)])
756 789
757 790 def get_absolute_url_stop(self):
758 791 return reverse('url_stop_dev_conf', args=[str(self.id)])
759 792
760 793 def get_absolute_url_status(self):
761 794 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,11 +1,11
1 1 @import url("https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700");/*!
2 2 * bootswatch v3.3.7
3 3 * Homepage: http://bootswatch.com
4 4 * Copyright 2012-2016 Thomas Park
5 5 * Licensed under MIT
6 6 * Based on Bootstrap
7 7 *//*!
8 8 * Bootstrap v3.3.7 (http://getbootstrap.com)
9 9 * Copyright 2011-2016 Twitter, Inc.
10 10 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11 *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-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:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}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{border:0;padding: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-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-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}.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.woff2') format('woff2'),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:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.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"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-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:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#666666;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#3399f3;text-decoration:none}a:hover,a:focus{color:#3399f3;text-decoration:underline}a:focus{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{padding:4px;line-height:1.42857143;background-color:#ffffff;border:1px solid #dddddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;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}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:#2d2d2d}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:normal;line-height:1;color:#999999}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{background-color:#fcf8e3;padding:.2em}.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:#999999}.text-primary{color:#446e9b}a.text-primary:hover,a.text-primary:focus{color:#345578}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-danger{color:#b94a48}a.text-danger:hover,a.text-danger:focus{color:#953b39}.bg-primary{color:#fff;background-color:#446e9b}a.bg-primary:hover,a.bg-primary:focus{background-color:#345578}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eeeeee}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;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eeeeee}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:#999999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;text-align:right}.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:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;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{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-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-left:15px;padding-right: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:#999999;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 #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.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 #dddddd}.table .table{background-color:#ffffff}.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 #dddddd}.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 #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.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{overflow-x:auto;min-height:0.01%}@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 #dddddd}.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{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#666666;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}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:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#666666}.form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#666666;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-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,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#999999;opacity:1}.form-control:-ms-input-placeholder{color:#999999}.form-control::-webkit-input-placeholder{color:#999999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eeeeee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:38px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:54px}}.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:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;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:9px;padding-bottom:9px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:54px;line-height:54px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:54px;line-height:54px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:47.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:54px;height:54px;line-height:54px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.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:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;border-color:#468847;background-color:#dff0d8}.has-success .form-control-feedback{color:#468847}.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:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;border-color:#c09853;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#c09853}.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:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;border-color:#b94a48;background-color:#f2dede}.has-error .form-control-feedback{color:#b94a48}.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:#a6a6a6}@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{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:29px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#ffffff;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#ffffff;background-color:#474949;border-color:#474949}.btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#2e2f2f;border-color:#080808}.btn-default:hover{color:#ffffff;background-color:#2e2f2f;border-color:#292a2a}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#2e2f2f;border-color:#292a2a}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#ffffff;background-color:#1c1d1d;border-color:#080808}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.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{background-color:#474949;border-color:#474949}.btn-default .badge{color:#474949;background-color:#ffffff}.btn-primary{color:#ffffff;background-color:#446e9b;border-color:#446e9b}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#345578;border-color:#1d2f42}.btn-primary:hover{color:#ffffff;background-color:#345578;border-color:#315070}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#345578;border-color:#315070}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#2a435f;border-color:#1d2f42}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.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{background-color:#446e9b;border-color:#446e9b}.btn-primary .badge{color:#446e9b;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#3cb521;border-color:#3cb521}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#2e8a19;border-color:#18490d}.btn-success:hover{color:#ffffff;background-color:#2e8a19;border-color:#2b8118}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#2e8a19;border-color:#2b8118}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#246c14;border-color:#18490d}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.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{background-color:#3cb521;border-color:#3cb521}.btn-success .badge{color:#3cb521;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#3399f3;border-color:#3399f3}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#0e80e5;border-color:#09589d}.btn-info:hover{color:#ffffff;background-color:#0e80e5;border-color:#0d7bdc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#0e80e5;border-color:#0d7bdc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#0c6dc4;border-color:#09589d}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.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{background-color:#3399f3;border-color:#3399f3}.btn-info .badge{color:#3399f3;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#d47500;border-color:#d47500}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#a15900;border-color:#552f00}.btn-warning:hover{color:#ffffff;background-color:#a15900;border-color:#975300}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#a15900;border-color:#975300}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#7d4500;border-color:#552f00}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.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{background-color:#d47500;border-color:#d47500}.btn-warning .badge{color:#d47500;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#cd0200;border-color:#cd0200}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#9a0200;border-color:#4e0100}.btn-danger:hover{color:#ffffff;background-color:#9a0200;border-color:#900100}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#9a0200;border-color:#900100}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#760100;border-color:#4e0100}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.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{background-color:#cd0200;border-color:#cd0200}.btn-danger .badge{color:#cd0200;background-color:#ffffff}.btn-link{color:#3399f3;font-weight:normal;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:#3399f3;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:#999999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:14px 16px;font-size:18px;line-height:1.3333333;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 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.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;list-style:none;font-size:14px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.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:normal;line-height:1.42857143;color:#333333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#446e9b}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#446e9b}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999999;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.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,.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-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-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:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,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-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;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-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;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-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;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:54px;line-height:54px}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:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#666666;text-align:center;background-color:#eeeeee;border:1px solid #cccccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:14px 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-bottom-right-radius:0;border-top-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-bottom-left-radius:0;border-top-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{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left: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:#eeeeee}.nav>li.disabled>a{color:#999999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#3399f3}.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 #dddddd}.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:#eeeeee #eeeeee #dddddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#666666;background-color:#ffffff;border:1px solid #dddddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.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 #dddddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;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:#ffffff}}.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:#ffffff;background-color:#446e9b}.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{text-align:center;margin-bottom:5px}.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 #dddddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;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:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-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{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.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}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right: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;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.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;margin-right:15px;padding:9px 10px;margin-top:8px;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{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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);margin-top:6px;margin-bottom:6px}@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;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:6px;margin-bottom:6px}.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-left:15px;margin-right: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:#eeeeee;border-color:#dddddd}.navbar-default .navbar-brand{color:#777777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-text{color:#777777}.navbar-default .navbar-nav>li>a{color:#777777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-default .navbar-toggle{border-color:#dddddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#dddddd}.navbar-default .navbar-toggle .icon-bar{background-color:#cccccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#dddddd}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:transparent;color:#3399f3}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#3399f3;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:#3399f3;background-color:transparent}.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:#444444;background-color:transparent}}.navbar-default .navbar-link{color:#777777}.navbar-default .navbar-link:hover{color:#3399f3}.navbar-default .btn-link{color:#777777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#3399f3}.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:#444444}.navbar-inverse{background-color:#446e9b;border-color:#345578}.navbar-inverse .navbar-brand{color:#dddddd}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#dddddd}.navbar-inverse .navbar-nav>li>a{color:#dddddd}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#345578}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#345578}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#395c82}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:transparent;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#345578}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#345578}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#dddddd}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;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:#ffffff;background-color:transparent}.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:#cccccc;background-color:transparent}}.navbar-inverse .navbar-link{color:#dddddd}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#dddddd}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.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:#cccccc}.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{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#999999}.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:8px 12px;line-height:1.42857143;text-decoration:none;color:#3399f3;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#3399f3;background-color:#eeeeee;border-color:#dddddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#999999;background-color:#f5f5f5;border-color:#dddddd;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999999;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:#ffffff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#474949}.label-default[href]:hover,.label-default[href]:focus{background-color:#2e2f2f}.label-primary{background-color:#446e9b}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#345578}.label-success{background-color:#3cb521}.label-success[href]:hover,.label-success[href]:focus{background-color:#2e8a19}.label-info{background-color:#3399f3}.label-info[href]:hover,.label-info[href]:focus{background-color:#0e80e5}.label-warning{background-color:#d47500}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#a15900}.label-danger{background-color:#cd0200}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#9a0200}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#3399f3;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#3399f3;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eeeeee}.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;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#ffffff;border:1px solid #dddddd;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-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#3399f3}.thumbnail .caption{padding:9px;color:#666666}.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:bold}.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{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{background-color:#fcf8e3;border-color:#fbeed5;color:#c09853}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-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{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#446e9b;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;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:#3cb521}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#3399f3}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#d47500}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#cd0200}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.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{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#999999;cursor:not-allowed}.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:#999999}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#446e9b;border-color:#446e9b}.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:#c5d5e6}.list-group-item-success{color:#468847;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#468847}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#468847;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#468847;border-color:#468847}.list-group-item-info{color:#3a87ad;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#3a87ad}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#3a87ad;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#3a87ad;border-color:#3a87ad}.list-group-item-warning{color:#c09853;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#c09853}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#c09853;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#c09853;border-color:#c09853}.list-group-item-danger{color:#b94a48;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#b94a48}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#b94a48;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#b94a48;border-color:#b94a48}.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:#ffffff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-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,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;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-right-radius:3px;border-top-left-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>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.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-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-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-left-radius:3px;border-bottom-right-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 #dddddd}.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{border:0;margin-bottom: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 #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#333333;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#446e9b}.panel-primary>.panel-heading{color:#ffffff;background-color:#446e9b;border-color:#446e9b}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#446e9b}.panel-primary>.panel-heading .badge{color:#446e9b;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#446e9b}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;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:#468847}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;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:#3a87ad}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#fbeed5}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#c09853}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#eed3d7}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#b94a48}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#eed3d7}.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;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.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,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.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:#ffffff;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{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:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.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,0.5);box-shadow:0 5px 15px rgba(0,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:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#000000;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:#000000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#ffffff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,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{margin:0;padding:8px 14px;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{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-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:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left: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;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;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;line-height:1;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%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,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:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right: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-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.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-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right: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}.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 !important}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 !important}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 !important}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 !important}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 !important}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}}.navbar{background-image:-webkit-linear-gradient(#fff, #eee 50%, #e4e4e4);background-image:-o-linear-gradient(#fff, #eee 50%, #e4e4e4);background-image:-webkit-gradient(linear, left top, left bottom, from(#fff), color-stop(50%, #eee), to(#e4e4e4));background-image:linear-gradient(#fff, #eee 50%, #e4e4e4);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe4e4e4', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #d5d5d5;text-shadow:0 1px 0 rgba(255,255,255,0.3)}.navbar-inverse{background-image:-webkit-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-o-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d94bf), color-stop(50%, #446e9b), to(#3e648d));background-image:linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d94bf', endColorstr='#ff3e648d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #345578;text-shadow:0 -1px 0 rgba(0,0,0,0.3)}.navbar-inverse .badge{background-color:#fff;color:#446e9b}.navbar .badge{text-shadow:none}.navbar-nav>li>a,.navbar-nav>li>a:hover{padding-top:17px;padding-bottom:13px;-webkit-transition:color ease-in-out .2s;-o-transition:color ease-in-out .2s;transition:color ease-in-out .2s}.navbar-brand,.navbar-brand:hover{-webkit-transition:color ease-in-out .2s;-o-transition:color ease-in-out .2s;transition:color ease-in-out .2s}.navbar .caret,.navbar .caret:hover{-webkit-transition:border-color ease-in-out .2s;-o-transition:border-color ease-in-out .2s;transition:border-color ease-in-out .2s}.navbar .dropdown-menu{text-shadow:none}.btn{text-shadow:0 -1px 0 rgba(0,0,0,0.3)}.btn-default{background-image:-webkit-linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-image:-o-linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d7070), color-stop(50%, #474949), to(#3d3f3f));background-image:linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d7070', endColorstr='#ff3d3f3f', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e2f2f}.btn-default:hover{background-image:-webkit-linear-gradient(#636565, #3d3f3f 50%, #333434);background-image:-o-linear-gradient(#636565, #3d3f3f 50%, #333434);background-image:-webkit-gradient(linear, left top, left bottom, from(#636565), color-stop(50%, #3d3f3f), to(#333434));background-image:linear-gradient(#636565, #3d3f3f 50%, #333434);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff636565', endColorstr='#ff333434', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #242525}.btn-primary{background-image:-webkit-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-o-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d94bf), color-stop(50%, #446e9b), to(#3e648d));background-image:linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d94bf', endColorstr='#ff3e648d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #345578}.btn-primary:hover{background-image:-webkit-linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-image:-o-linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-image:-webkit-gradient(linear, left top, left bottom, from(#5f8ab9), color-stop(50%, #3e648d), to(#385a7f));background-image:linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5f8ab9', endColorstr='#ff385a7f', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e4b69}.btn-success{background-image:-webkit-linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-image:-o-linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-image:-webkit-gradient(linear, left top, left bottom, from(#61dd45), color-stop(50%, #3cb521), to(#36a41e));background-image:linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff61dd45', endColorstr='#ff36a41e', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e8a19}.btn-success:hover{background-image:-webkit-linear-gradient(#52da34, #36a41e 50%, #31921b);background-image:-o-linear-gradient(#52da34, #36a41e 50%, #31921b);background-image:-webkit-gradient(linear, left top, left bottom, from(#52da34), color-stop(50%, #36a41e), to(#31921b));background-image:linear-gradient(#52da34, #36a41e 50%, #31921b);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff52da34', endColorstr='#ff31921b', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #287916}.btn-info{background-image:-webkit-linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-image:-o-linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-image:-webkit-gradient(linear, left top, left bottom, from(#7bbdf7), color-stop(50%, #3399f3), to(#208ff2));background-image:linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff7bbdf7', endColorstr='#ff208ff2', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #0e80e5}.btn-info:hover{background-image:-webkit-linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-image:-o-linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-image:-webkit-gradient(linear, left top, left bottom, from(#68b3f6), color-stop(50%, #208ff2), to(#0e86ef));background-image:linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff68b3f6', endColorstr='#ff0e86ef', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #0c75d2}.btn-warning{background-image:-webkit-linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-image:-o-linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff9c21), color-stop(50%, #d47500), to(#c06a00));background-image:linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff9c21', endColorstr='#ffc06a00', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #a15900}.btn-warning:hover{background-image:-webkit-linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-image:-o-linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff930d), color-stop(50%, #c06a00), to(#ab5e00));background-image:linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff930d', endColorstr='#ffab5e00', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #8d4e00}.btn-danger{background-image:-webkit-linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-image:-o-linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff1d1b), color-stop(50%, #cd0200), to(#b90200));background-image:linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff1d1b', endColorstr='#ffb90200', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #9a0200}.btn-danger:hover{background-image:-webkit-linear-gradient(#ff0906, #b90200 50%, #a40200);background-image:-o-linear-gradient(#ff0906, #b90200 50%, #a40200);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff0906), color-stop(50%, #b90200), to(#a40200));background-image:linear-gradient(#ff0906, #b90200 50%, #a40200);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0906', endColorstr='#ffa40200', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #860100}.btn-link{text-shadow:none}.btn:active,.btn.active{background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.panel-primary .panel-title{color:#fff} No newline at end of file
11 *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-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:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}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{border:0;padding: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-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-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}.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.woff2') format('woff2'),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:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.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"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-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:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#666666;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#3399f3;text-decoration:none}a:hover,a:focus{color:#3399f3;text-decoration:underline}a:focus{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{padding:4px;line-height:1.42857143;background-color:#ffffff;border:1px solid #dddddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;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}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1;color:#2d2d2d}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:normal;line-height:1;color:#999999}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{background-color:#fcf8e3;padding:.2em}.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:#999999}.text-primary{color:#446e9b}a.text-primary:hover,a.text-primary:focus{color:#345578}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-danger{color:#b94a48}a.text-danger:hover,a.text-danger:focus{color:#953b39}.bg-primary{color:#fff;background-color:#446e9b}a.bg-primary:hover,a.bg-primary:focus{background-color:#345578}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px}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;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eeeeee}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:#999999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;text-align:right}.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:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;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{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-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-left:15px;padding-right: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:#999999;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 #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.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 #dddddd}.table .table{background-color:#ffffff}.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 #dddddd}.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 #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.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{overflow-x:auto;min-height:0.01%}@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 #dddddd}.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{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#666666;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}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:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#666666}.form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#666666;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-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,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#999999;opacity:1}.form-control:-ms-input-placeholder{color:#999999}.form-control::-webkit-input-placeholder{color:#999999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eeeeee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:38px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:54px}}.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:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;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:9px;padding-bottom:9px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:54px;line-height:54px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:54px;line-height:54px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:47.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:54px;height:54px;line-height:54px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.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:#468847}.has-success .form-control{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.has-success .input-group-addon{color:#468847;border-color:#468847;background-color:#dff0d8}.has-success .form-control-feedback{color:#468847}.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:#c09853}.has-warning .form-control{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.has-warning .input-group-addon{color:#c09853;border-color:#c09853;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#c09853}.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:#b94a48}.has-error .form-control{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.has-error .input-group-addon{color:#b94a48;border-color:#b94a48;background-color:#f2dede}.has-error .form-control-feedback{color:#b94a48}.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:#a6a6a6}@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{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:29px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#ffffff;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#ffffff;background-color:#474949;border-color:#474949}.btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#2e2f2f;border-color:#080808}.btn-default:hover{color:#ffffff;background-color:#2e2f2f;border-color:#292a2a}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#2e2f2f;border-color:#292a2a}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#ffffff;background-color:#1c1d1d;border-color:#080808}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.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{background-color:#474949;border-color:#474949}.btn-default .badge{color:#474949;background-color:#ffffff}.btn-primary{color:#ffffff;background-color:#446e9b;border-color:#446e9b}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#345578;border-color:#1d2f42}.btn-primary:hover{color:#ffffff;background-color:#345578;border-color:#315070}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#345578;border-color:#315070}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#2a435f;border-color:#1d2f42}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.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{background-color:#446e9b;border-color:#446e9b}.btn-primary .badge{color:#446e9b;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#3cb521;border-color:#3cb521}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#2e8a19;border-color:#18490d}.btn-success:hover{color:#ffffff;background-color:#2e8a19;border-color:#2b8118}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#2e8a19;border-color:#2b8118}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#246c14;border-color:#18490d}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.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{background-color:#3cb521;border-color:#3cb521}.btn-success .badge{color:#3cb521;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#3399f3;border-color:#3399f3}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#0e80e5;border-color:#09589d}.btn-info:hover{color:#ffffff;background-color:#0e80e5;border-color:#0d7bdc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#0e80e5;border-color:#0d7bdc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#0c6dc4;border-color:#09589d}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.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{background-color:#3399f3;border-color:#3399f3}.btn-info .badge{color:#3399f3;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#d47500;border-color:#d47500}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#a15900;border-color:#552f00}.btn-warning:hover{color:#ffffff;background-color:#a15900;border-color:#975300}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#a15900;border-color:#975300}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#7d4500;border-color:#552f00}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.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{background-color:#d47500;border-color:#d47500}.btn-warning .badge{color:#d47500;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#cd0200;border-color:#cd0200}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#9a0200;border-color:#4e0100}.btn-danger:hover{color:#ffffff;background-color:#9a0200;border-color:#900100}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#9a0200;border-color:#900100}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#760100;border-color:#4e0100}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.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{background-color:#cd0200;border-color:#cd0200}.btn-danger .badge{color:#cd0200;background-color:#ffffff}.btn-link{color:#3399f3;font-weight:normal;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:#3399f3;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:#999999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:14px 16px;font-size:18px;line-height:1.3333333;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 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.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;list-style:none;font-size:14px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.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:normal;line-height:1.42857143;color:#333333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#446e9b}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#446e9b}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999999;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.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,.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-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-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:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,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-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;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-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;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-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;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:54px;line-height:54px}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:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#666666;text-align:center;background-color:#eeeeee;border:1px solid #cccccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:14px 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-bottom-right-radius:0;border-top-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-bottom-left-radius:0;border-top-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{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left: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:#eeeeee}.nav>li.disabled>a{color:#999999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#3399f3}.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 #dddddd}.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:#eeeeee #eeeeee #dddddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#666666;background-color:#ffffff;border:1px solid #dddddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.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 #dddddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;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:#ffffff}}.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:#ffffff;background-color:#446e9b}.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{text-align:center;margin-bottom:5px}.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 #dddddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;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:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-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{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.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}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right: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;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.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;margin-right:15px;padding:9px 10px;margin-top:8px;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{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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);margin-top:6px;margin-bottom:6px}@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;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:6px;margin-bottom:6px}.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-left:15px;margin-right: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:#eeeeee;border-color:#dddddd}.navbar-default .navbar-brand{color:#777777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-text{color:#777777}.navbar-default .navbar-nav>li>a{color:#777777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#3399f3;background-color:transparent}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-default .navbar-toggle{border-color:#dddddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#dddddd}.navbar-default .navbar-toggle .icon-bar{background-color:#cccccc}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#dddddd}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:transparent;color:#3399f3}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#3399f3;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:#3399f3;background-color:transparent}.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:#444444;background-color:transparent}}.navbar-default .navbar-link{color:#777777}.navbar-default .navbar-link:hover{color:#3399f3}.navbar-default .btn-link{color:#777777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#3399f3}.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:#444444}.navbar-inverse{background-color:#446e9b;border-color:#345578}.navbar-inverse .navbar-brand{color:#dddddd}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#dddddd}.navbar-inverse .navbar-nav>li>a{color:#dddddd}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#345578}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#345578}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#395c82}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:transparent;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#345578}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#345578}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#dddddd}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;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:#ffffff;background-color:transparent}.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:#cccccc;background-color:transparent}}.navbar-inverse .navbar-link{color:#dddddd}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#dddddd}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.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:#cccccc}.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{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#999999}.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:8px 12px;line-height:1.42857143;text-decoration:none;color:#3399f3;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#3399f3;background-color:#eeeeee;border-color:#dddddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#999999;background-color:#f5f5f5;border-color:#dddddd;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999999;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:#ffffff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#474949}.label-default[href]:hover,.label-default[href]:focus{background-color:#2e2f2f}.label-primary{background-color:#446e9b}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#345578}.label-success{background-color:#3cb521}.label-success[href]:hover,.label-success[href]:focus{background-color:#2e8a19}.label-info{background-color:#3399f3}.label-info[href]:hover,.label-info[href]:focus{background-color:#0e80e5}.label-warning{background-color:#d47500}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#a15900}.label-danger{background-color:#cd0200}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#9a0200}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#3399f3;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#3399f3;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eeeeee}.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;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#ffffff;border:1px solid #dddddd;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-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#3399f3}.thumbnail .caption{padding:9px;color:#666666}.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:bold}.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{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#356635}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#2d6987}.alert-warning{background-color:#fcf8e3;border-color:#fbeed5;color:#c09853}.alert-warning hr{border-top-color:#f8e5be}.alert-warning .alert-link{color:#a47e3c}.alert-danger{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}.alert-danger hr{border-top-color:#e6c1c7}.alert-danger .alert-link{color:#953b39}@-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{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#446e9b;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;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:#3cb521}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#3399f3}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#d47500}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#cd0200}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.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{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#999999;cursor:not-allowed}.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:#999999}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#446e9b;border-color:#446e9b}.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:#c5d5e6}.list-group-item-success{color:#468847;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#468847}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#468847;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#468847;border-color:#468847}.list-group-item-info{color:#3a87ad;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#3a87ad}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#3a87ad;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#3a87ad;border-color:#3a87ad}.list-group-item-warning{color:#c09853;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#c09853}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#c09853;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#c09853;border-color:#c09853}.list-group-item-danger{color:#b94a48;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#b94a48}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#b94a48;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#b94a48;border-color:#b94a48}.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:#ffffff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-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,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;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-right-radius:3px;border-top-left-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>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.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-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-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-left-radius:3px;border-bottom-right-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 #dddddd}.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{border:0;margin-bottom: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 #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#333333;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#446e9b}.panel-primary>.panel-heading{color:#ffffff;background-color:#446e9b;border-color:#446e9b}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#446e9b}.panel-primary>.panel-heading .badge{color:#446e9b;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#446e9b}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#468847;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:#468847}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#3a87ad;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:#3a87ad}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#fbeed5}.panel-warning>.panel-heading{color:#c09853;background-color:#fcf8e3;border-color:#fbeed5}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#fbeed5}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#c09853}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#fbeed5}.panel-danger{border-color:#eed3d7}.panel-danger>.panel-heading{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#eed3d7}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#b94a48}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#eed3d7}.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;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.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,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.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:#ffffff;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{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:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.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,0.5);box-shadow:0 5px 15px rgba(0,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:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#000000;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:#000000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#ffffff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,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{margin:0;padding:8px 14px;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{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-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:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left: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;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;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;line-height:1;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%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,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:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right: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-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.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-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right: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}.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 !important}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 !important}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 !important}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 !important}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 !important}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}}.navbar{background-image:-webkit-linear-gradient(#fff, #eee 50%, #e4e4e4);background-image:-o-linear-gradient(#fff, #eee 50%, #e4e4e4);background-image:-webkit-gradient(linear, left top, left bottom, from(#fff), color-stop(50%, #eee), to(#e4e4e4));background-image:linear-gradient(#fff, #eee 50%, #e4e4e4);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe4e4e4', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #d5d5d5;text-shadow:0 1px 0 rgba(255,255,255,0.3)}.navbar-inverse{background-image:-webkit-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-o-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d94bf), color-stop(50%, #446e9b), to(#3e648d));background-image:linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d94bf', endColorstr='#ff3e648d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #345578;text-shadow:0 -1px 0 rgba(0,0,0,0.3)}.navbar-inverse .badge{background-color:#fff;color:#446e9b}.navbar .badge{text-shadow:none}.navbar-nav>li>a,.navbar-nav>li>a:hover{padding-top:17px;padding-bottom:13px;-webkit-transition:color ease-in-out .2s;-o-transition:color ease-in-out .2s;transition:color ease-in-out .2s}.navbar-brand,.navbar-brand:hover{-webkit-transition:color ease-in-out .2s;-o-transition:color ease-in-out .2s;transition:color ease-in-out .2s}.navbar .caret,.navbar .caret:hover{-webkit-transition:border-color ease-in-out .2s;-o-transition:border-color ease-in-out .2s;transition:border-color ease-in-out .2s}.navbar .dropdown-menu{text-shadow:none}.btn{text-shadow:0 -1px 0 rgba(0,0,0,0.3)}.btn-default{background-image:-webkit-linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-image:-o-linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d7070), color-stop(50%, #474949), to(#3d3f3f));background-image:linear-gradient(#6d7070, #474949 50%, #3d3f3f);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d7070', endColorstr='#ff3d3f3f', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e2f2f}.btn-default:hover{background-image:-webkit-linear-gradient(#636565, #3d3f3f 50%, #333434);background-image:-o-linear-gradient(#636565, #3d3f3f 50%, #333434);background-image:-webkit-gradient(linear, left top, left bottom, from(#636565), color-stop(50%, #3d3f3f), to(#333434));background-image:linear-gradient(#636565, #3d3f3f 50%, #333434);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff636565', endColorstr='#ff333434', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #242525}.btn-primary{background-image:-webkit-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-o-linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-image:-webkit-gradient(linear, left top, left bottom, from(#6d94bf), color-stop(50%, #446e9b), to(#3e648d));background-image:linear-gradient(#6d94bf, #446e9b 50%, #3e648d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d94bf', endColorstr='#ff3e648d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #345578}.btn-primary:hover{background-image:-webkit-linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-image:-o-linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-image:-webkit-gradient(linear, left top, left bottom, from(#5f8ab9), color-stop(50%, #3e648d), to(#385a7f));background-image:linear-gradient(#5f8ab9, #3e648d 50%, #385a7f);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5f8ab9', endColorstr='#ff385a7f', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e4b69}.btn-success{background-image:-webkit-linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-image:-o-linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-image:-webkit-gradient(linear, left top, left bottom, from(#61dd45), color-stop(50%, #3cb521), to(#36a41e));background-image:linear-gradient(#61dd45, #3cb521 50%, #36a41e);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff61dd45', endColorstr='#ff36a41e', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #2e8a19}.btn-success:hover{background-image:-webkit-linear-gradient(#52da34, #36a41e 50%, #31921b);background-image:-o-linear-gradient(#52da34, #36a41e 50%, #31921b);background-image:-webkit-gradient(linear, left top, left bottom, from(#52da34), color-stop(50%, #36a41e), to(#31921b));background-image:linear-gradient(#52da34, #36a41e 50%, #31921b);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff52da34', endColorstr='#ff31921b', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #287916}.btn-info{background-image:-webkit-linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-image:-o-linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-image:-webkit-gradient(linear, left top, left bottom, from(#7bbdf7), color-stop(50%, #3399f3), to(#208ff2));background-image:linear-gradient(#7bbdf7, #3399f3 50%, #208ff2);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff7bbdf7', endColorstr='#ff208ff2', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #0e80e5}.btn-info:hover{background-image:-webkit-linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-image:-o-linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-image:-webkit-gradient(linear, left top, left bottom, from(#68b3f6), color-stop(50%, #208ff2), to(#0e86ef));background-image:linear-gradient(#68b3f6, #208ff2 50%, #0e86ef);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff68b3f6', endColorstr='#ff0e86ef', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #0c75d2}.btn-warning{background-image:-webkit-linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-image:-o-linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff9c21), color-stop(50%, #d47500), to(#c06a00));background-image:linear-gradient(#ff9c21, #d47500 50%, #c06a00);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff9c21', endColorstr='#ffc06a00', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #a15900}.btn-warning:hover{background-image:-webkit-linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-image:-o-linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff930d), color-stop(50%, #c06a00), to(#ab5e00));background-image:linear-gradient(#ff930d, #c06a00 50%, #ab5e00);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff930d', endColorstr='#ffab5e00', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #8d4e00}.btn-danger{background-image:-webkit-linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-image:-o-linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff1d1b), color-stop(50%, #cd0200), to(#b90200));background-image:linear-gradient(#ff1d1b, #cd0200 50%, #b90200);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff1d1b', endColorstr='#ffb90200', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #9a0200}.btn-danger:hover{background-image:-webkit-linear-gradient(#ff0906, #b90200 50%, #a40200);background-image:-o-linear-gradient(#ff0906, #b90200 50%, #a40200);background-image:-webkit-gradient(linear, left top, left bottom, from(#ff0906), color-stop(50%, #b90200), to(#a40200));background-image:linear-gradient(#ff0906, #b90200 50%, #a40200);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0906', endColorstr='#ffa40200', GradientType=0);-webkit-filter:none;filter:none;border:1px solid #860100}.btn-link{text-shadow:none}.btn:active,.btn.active{background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.panel-primary .panel-title{color:#fff} No newline at end of file
@@ -1,172 +1,165
1 1 <!DOCTYPE html>
2 2 {% load static %}
3 3 <html lang="en">
4 4 <head>
5 5 <meta charset="utf-8">
6 6 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
7 7 <meta name="description" content="">
8 8 <meta name="author" content="">
9 9 <meta name="viewport" content="width=device-width, initial-scale=1">
10 10 {# bootstrap_css #}
11 11
12 <link href="{% static 'css/bootstrap-spacelab.min.css' %}" media="all" rel="stylesheet">
12 <link href="{% static 'css/bootstrap-yeti.min.css' %}" media="all" rel="stylesheet">
13 13 <link href="{% static 'css/bootcards-desktop.min.css' %}" media="all" rel="stylesheet">
14 14 <link href="{% static 'css/font-awesome.min.css' %}" media="all" rel="stylesheet">
15 15 <!--link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"-->
16 16
17 17 <!-- Bootcards CSS for iOS: >
18 18 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-ios.min.css">
19 19
20 20 <!-- Bootcards CSS for Android: >
21 21 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-android.min.css"-->
22 22
23 23 <!-- Bootcards CSS for desktop: >
24 24 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-desktop.min.css"-->
25 25
26 26
27 27 <style type="text/css">
28 28 body {padding-top: 60px}
29 29 .logo {padding-top: 5px; height: 50px}
30 30 .clickable-row {cursor: pointer;}
31 31 .col-no-padding { padding-left:0;}
32 32 .gi-2x{font-size: 2em;}
33 33 .gi-3x{font-size: 3em;}
34 34 .gi-4x{font-size: 4em;}
35 35 .gi-5x{font-size: 5em;}
36 36 </style>
37 37 <!--[if lt IE 9]>
38 38 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
39 39 <![endif]-->
40 40 <script src="{% static 'js/jquery.min.js' %}"></script>
41 41 {% block extra-head %}
42 42 {% endblock %}
43 43 </head>
44 44
45 45 <body>
46 46
47 47 {% block main_menu %}
48 48 <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
49 49 <div class="container-fluid">
50 50 <div class="navbar-header">
51 51 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navigationbar">
52 52 <span class="sr-only">Toggle navigation</span>
53 53 <span class="icon-bar"></span>
54 54 <span class="icon-bar"></span>
55 55 <span class="icon-bar"></span>
56 56 </button>
57 57 <a class="navbar-brand" href="{% url 'index' %}" style="padding-top:1px"><img class="logo" alt="JRO" src="{% static "images/logo-jro-color-trans.png" %}"></a>
58 58 </div>
59 59 <div class="collapse navbar-collapse" id="navigationbar">
60 60 <ul class="nav navbar-nav">
61 <li class=" dropdown {% block operation-active %}{% endblock %}"><a href="{% url 'url_operation'%}">Operation</a>
61 <li class=" dropdown {% block operation-active %}{% endblock %}">
62 <a href="{% url 'url_operation'%}">Operation</a>
62 63 </li>
63 <li class=" dropdown {% block new-active %}{% endblock %}">
64 <a href="#" class="dropdown-toggle" data-toggle="dropdown">New<span class="caret"></span></a>
65 <ul class="dropdown-menu" role="menu">
66 <li><a href="{% url 'url_add_campaign' %}">Campaign</a></li>
67 <li><a href="{% url 'url_add_experiment' %}">Experiment</a></li>
68 <li><a href="{% url 'url_add_dev_conf' 0%}">Device Configuration</a></li>
69 <li><a href="{% url 'url_add_device'%}">Device</a></li>
70 <li><a href="{% url 'url_add_location'%}">Radar System</a></li>
71 </ul>
64 <li class=" dropdown {% block campaign-active %}{% endblock %}">
65 <a href="{% url 'url_campaigns'%}">Campaigns</a>
72 66 </li>
73 <li class=" dropdown {% block search-active %}{% endblock %}">
74 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<span class="caret"></span></a>
75 <ul class="dropdown-menu" role="menu">
76 <li><a href="{% url 'url_campaigns' %}">Campaigns</a></li>
77 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
78 <li><a href="{% url 'url_dev_confs' %}">Configurations</a></li>
79 <li><a href="{% url 'url_devices' %}">Devices</a></li>
80 <li><a href="{% url 'url_locations' %}">Radar Systems</a></li>
81 </ul>
67 <li class=" dropdown {% block experiment-active %}{% endblock %}">
68 <a href="{% url 'url_experiments'%}">Experiments</a>
69 </li>
70 <li class=" dropdown {% block configuration-active %}{% endblock %}">
71 <a href="{% url 'url_dev_confs'%}">Configurations</a>
72 </li>
73 <li class=" dropdown {% block device-active %}{% endblock %}">
74 <a href="{% url 'url_devices'%}">Devices</a>
82 75 </li>
83 76 </ul>
84 77 <ul class="nav navbar-nav navbar-right">
85 78 <li class="nav-divider"></li>
86 79 {% if user.is_authenticated %}
87 80 <li class="dropdown">
88 81 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi {{ user.username }}<span class="caret"></span></a>
89 82 <ul class="dropdown-menu" role="menu">
90 <li><a href="/admin">Control Panel</a></li>
83 <li><a href="/admin" target="_blank">Control Panel</a></li>
91 84 <li><a href="{% url 'url_logout' %}">Logout</a></li>
92 85 </ul>
93 86 </li>
94 87 {% else %}
95 88 <li><a href="{% url 'url_login' %}?next={{request.get_full_path}}">Login</a></li>
96 89 {% endif %}
97 90 </ul>
98 91 </div>
99 92 </div>
100 93 </nav>
101 94 <div style="clear: both;"></div>
102 95 {% endblock %}
103 96
104 97 <div class="container">
105 98 <div id="page" class="row" style="min-height:600px">
106 99
107 100 {% if no_sidebar %}
108 101 <div class="col-md-0 hidden-xs hidden-sm" role="complementary"></div>
109 102
110 103 {% else %}
111 104 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
112 105 <br><br>
113 106 <div id="sidebar">
114 107 {% block sidebar%}
115 108 {% include "sidebar_devices.html" %}
116 109 {% endblock %}
117 110 </div>
118 111 </div>
119 112 {% endif %}
120 113
121 114
122 115 {% if no_sidebar %}
123 116 <div class="col-md-12 col-xs-12" role="main">
124 117 {% else %}
125 118 <div class="col-md-9 col-xs-12" role="main">
126 119 {% endif %}
127 120 <div class="page-header">
128 121 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
129 122 </div>
130 123 {% block messages %}
131 124 {% if messages %}
132 125 {% for message in messages %}
133 126 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
134 127 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
135 128 <strong>{{message.tags|title}}!</strong> {{ message }}
136 129 </div>
137 130 {% endfor %}
138 131 {% endif %}
139 132 {% endblock %}
140 133
141 134 {% block content %}
142 135 {% endblock %}
143 136
144 137 </div>
145 138
146 139
147 140 </div><!--/row-->
148 141 </div> <!-- container -->
149 142
150 143 <div id="debug">{{debug}}</div>
151 144
152 145 {% block footer %}
153 146 <footer class="footer">
154 147 <div class="container">
155 148 <p><hr></p>
156 149 <p>
157 150 &copy; <a href="http://jro.igp.gob.pe">Jicamarca Radio Observatory</a> - {% now "Y" %}
158 151 </p>
159 152 </div>
160 153 </footer>
161 154 {% endblock %}
162 155
163 156 {# bootstrap_javascript jquery=True #}
164 157
165 158 <script src="{% static 'js/bootstrap.min.js' %}"></script>
166 159 <script src="{% static 'js/bootcards.min.js' %}"></script>
167 160 <!-- Bootstrap and Bootcards JS >
168 161 <script src="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/js/bootcards.min.js"></script-->
169 162 {% block extra-js %}
170 163 {% endblock%}
171 164 </body>
172 165 </html>
@@ -1,74 +1,85
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-head %}
7 7 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
8 8 {% endblock %}
9 9
10 {% block search-active %}active{% endblock %}
10 {% block {{menu}}-active %}active{% endblock %}
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 {% block content-filter %}
17 17 {% if form %}
18 18 <form class="form" method="get">
19 19 {% bootstrap_form form layout='horizontal' size='medium' %}
20 20 <div class="pull-right">
21 <br>
21 22 <button type="button" class="btn btn-primary btn-sm" onclick="window.location.replace('?');"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
22 23 <button type="submit" class="btn btn-primary btn-sm"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
23 </div>
24 {% if add_url %}
25 <a class="btn btn-sm btn-info" href="{{add_url}}"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></a>
26 {% endif %}
27 </div>
24 28 </form>
25 29 {% endif %}
26 30 {% endblock %}
27 31 <div style="clear: both;"></div>
28 32 <br>
29 33 <table class="table table-hover">
30 34 <tr>
31 35 <th>#</th>
32 36 {% for key in keys %}
33 37 <th>{{ key|title }}</th>
34 38 {% endfor%}
35 39 </tr>
36 40 {% for object in objects %}
37 41 <tr class="clickable-row" data-href="{{object.get_absolute_url}}">
38 42 <td>{{ forloop.counter|add:offset }}</td>
39 43 {% for key in keys %}
44 {% if key == 'actions' %}
45 <td>
46 <a class="btn btn-sm btn-danger" href="{{object.get_absolute_url_delete}}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
47 <a class="btn btn-sm btn-primary" href="{{object.get_absolute_url_edit}}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
48 </td>
49 {% else %}
40 50 <td>{{ object|attr:key }}</td>
51 {% endif %}
41 52 {% endfor %}
42 53 </tr>
43 54 {% endfor %}
44 55 </table>
45 56
46 57 <div class="pagination">
47 58 <span class="step-links">
48 59 {% if objects.has_previous %}
49 60 <a href="?page={{ objects.previous_page_number }}&{{q}}"><span class="glyphicon glyphicon-menu-left" aria-hidden="true"></span></a>
50 61 {% endif %}
51 62 <span class="current">
52 63 Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
53 64 </span>
54 65 {% if objects.has_next %}
55 66 <a href="?page={{ objects.next_page_number }}&{{q}}"><span class="glyphicon glyphicon-menu-right aria-hidden="true"></span></a>
56 67 {% endif %}
57 68 </span>
58 69 </div>
59 70
60 71 {% endblock %}
61 72
62 73 {% block extra-js%}
63 74 <script src="{% static 'js/moment.min.js' %}"></script>
64 75 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
65 76 <script type="text/javascript">
66 77
67 78 $('.input-group.date').datetimepicker({"format": "YYYY-MM-DD"});
68 79
69 80 $(".clickable-row").click(function() {
70 81 document.location = $(this).data("href");
71 82 });
72 83
73 84 </script>
74 85 {% endblock %}
@@ -1,84 +1,82
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block search-active %}active{% endblock %}
7 7
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12
13 13 {% block menu-actions %}
14 14 <span class=" dropdown pull-right">
15 15 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
16 16 <ul class="dropdown-menu" role="menu">
17 17 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
18 <li><a href="{% url 'url_delete_dev_conf' dev_conf.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
18 <li><a href="{{ dev_conf.get_absolute_url_delete }}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
19 19 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
20 20 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
21 21 {% block extra-menu-actions %}
22 22 {% endblock %}
23 23 <li><a>----------------</a></li>
24 24 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
25 25 {% if not no_play %}
26 26 {% if not only_stop %}
27 27 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
28 28 {% endif %}
29 29 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
30 30 {% endif %}
31 31 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
32 32 {% if dev_conf.device.device_type.name != 'abs' %}
33 33 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
34 34 {% endif %}
35 35 </ul>
36 36 </span>
37 37 {% endblock %}
38 38
39 39 <table class="table table-bordered">
40 40 <tr>
41 41 <th>Status</th>
42 42 <td class="text-{{dev_conf.device.status_color}}"><strong> {% if dev_conf.device.device_type.name == 'abs' %} {{connected_modules}} {% else %} {{dev_conf.device.get_status_display}}{% endif %}</strong></td>
43 43 </tr>
44 44
45 45 {% for key in dev_conf_keys %}
46 46 <tr>
47 47 <th>{% get_verbose_field_name dev_conf key %}</th>
48 48 <td>{{dev_conf|attr:key}}</td>
49 49 </tr>
50 50 {% endfor %}
51 51 </table>
52 52
53 53 {% block extra-content %}
54 54 {% endblock %}
55 55
56 56 {% endblock %}
57 57
58
59
60 58 {% block extra-js%}
61 59 <script type="text/javascript">
62 60
63 61 $("#bt_edit").click(function() {
64 62 document.location = "{{ dev_conf.get_absolute_url_edit }}";
65 63 });
66 64
67 65 $("#bt_read").click(function() {
68 66 document.location = "{{ dev_conf.get_absolute_url_read }}";
69 67 });
70 68
71 69 $("#bt_write").click(function() {
72 70 document.location = "{{ dev_conf.get_absolute_url_write }}";
73 71 });
74 72
75 73 $("#bt_import").click(function() {
76 74 document.location = "{{ dev_conf.get_absolute_url_import }}";
77 75 });
78 76
79 77 $("#bt_export").click(function() {
80 78 document.location = "{{ dev_conf.get_absolute_url_export }}";
81 79 });
82 80
83 81 </script>
84 82 {% endblock %}
@@ -1,109 +1,62
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 {% endblock %}
8 8
9 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 <table class="table table-bordered">
17 17 {% for key in experiment_keys %}
18 18 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
19 19 {% endfor %}
20 20 <tr><th>Lambda (m)</th><td>{{radar_lambda}}</td></tr>
21 21 </table>
22 22
23 23
24 {% for configuration in configurations %}
24 {% for conf in configurations %}
25 25
26 26 <div class="">
27 <h4 class="panel-title"><b> {{configuration}}</b></h4>
27 <h4 class="panel-title"><b> {{conf.conf}}</b></h4>
28 28 <br>
29 29 </div>
30 30
31 {% if configuration.device.device_type.name == 'dds' %}
32 <table class="table table-bordered">
33 <tr><th>Frequency A (Mhz)</th><td>{{configuration.frequencyA_Mhz}}</td></tr>
34 <tr><th>Multiplier</th><td>{{configuration.multiplier}}</td></tr>
35 </table>
36 {% endif %}
37
38 {% if configuration.device.device_type.name == 'rc' %}
39
40 <table class="table table-bordered">
41 <!--<h4 class="panel-title"> </h4>-->
42 <tr><th>NTXs</th><td>{{configuration.ntx}}</td></tr>
43 <tr><th>IPP(km)</th><td>{{configuration.ipp}}</td></tr>
44 <tr><th>DC</th><td>{{duty_cycle}}%</td></tr>
45
46 {% for tx_line in configuration.tx_lines %}
47 <tr><th colspan="2">{{tx_line.name}}</th></tr>
48 <tr><th>Width(km)</th><td>{{tx_line.width}}</td></tr>
49 <tr><th>Taus</th><td>{{tx_line.taus}}</td></tr>
50 <tr><th>codes</th><td>{{tx_line.codes}}</td></tr>
51 <tr><th>Sample Windows</th><td>{{tx_line.windows}}</td></tr>
52 {% endfor %}
53
54 </table>
55 {% endif %}
56
57 {% if configuration.device.device_type.name == 'jars' %}
58
59 <table class="table table-bordered">
60 <!--<h4 class="panel-title"> JARS </h4>-->
61 <tr><th>Data Type</th><td>{{exp_type}}</td></tr>
62 <tr><th># Channels</th><td>{{configuration.channels_number}}</td></tr>
63 <tr><th>Coh Int</th><td>{{configuration.cohe_integr}}</td></tr>
64 <tr><th>FFT Points</th><td>{{configuration.fftpoints}}</td></tr>
65 {% if exp_type == 'PDATA'%}
66 <tr><th>Inc Int</th><td>{{configuration.incohe_integr}}</td></tr>
67 <tr><th>Spec. Comb.</th><td>{{configuration.spectral}}</td></tr>
68 {% endif %}
69 <tr><th>Acq Prof</th><td>{{configuration.acq_profiles}}</td></tr>
70 <tr><th>Prof x Block</th><td>{{configuration.profiles_block}}</td></tr>
71 <tr><th>Block x File</th><td>{{ configuration.raw_data_blocks }}</td></tr>
72 <tr><th>Time per Block (s)</th><td>{{ time_per_block }}</td></tr>
73 <tr><th>Acqtime (s)</th><td>{{ acqtime }}</td></tr>
74 <tr><th>Rate </th><td>{{ rate_bh }} || {{ rate_gh }}</td></tr>
75 <tr><th>Va (m/s)</th><td>{{ va }}</td></tr>
76 <tr><th>Vrange (m/s)</th><td>{{ vrange }}</td></tr>
77 </table>
78 {% endif %}
31 <table class="table table-bordered">
32 {% for key in conf.keys %}
33 <tr><th>{{key}}</th><td>{{conf|attr:key}}</td></tr>
34 {% endfor %}
35 </table>
79 36
80 37 {% endfor %}
81 38
82 39 <div class="pull-right">
83 40 <button type="button" class="btn btn-primary" id="bt_back">Back</button>
84 41 <button type="button" class="btn btn-primary" id="bt_verify">Verify Parameters</button>
85 42 </div>
86 43
87 44 {% endblock %}
88 45
89 46 {% block sidebar%}
90 47 {% include "sidebar_devices.html" %}
91 48 {% endblock %}
92 49
93 50 {% block extra-js%}
94 51 <script type="text/javascript">
95 52
96 $(".clickable-row").click(function() {
97 document.location = $(this).data("href");
98 });
99
100 53 $("#bt_back").click(function() {
101 54 document.location = "{% url 'url_experiment' experiment.id%}";
102 55 });
103 56
104 57 $("#bt_verify").click(function() {
105 58 document.location = "{% url 'url_verify_experiment' experiment.id%}";
106 59 });
107 60
108 61 </script>
109 62 {% endblock %}
This diff has been collapsed as it changes many lines, (839 lines changed) Show them Hide them
@@ -1,1736 +1,1821
1 1 import ast
2 2 import json
3 import hashlib
3 4 from datetime import datetime, timedelta
4 5
5 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 7 from django.utils.safestring import mark_safe
7 8 from django.http import HttpResponseRedirect
8 9 from django.core.urlresolvers import reverse
9 10 from django.db.models import Q
10 11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 12 from django.contrib import messages
12 13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
13 15
14 16 try:
15 17 from urllib.parse import urlencode
16 18 except ImportError:
17 19 from urllib import urlencode
18 20
19 21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
20 22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
21 23
22 24 from .tasks import task_start
23 25
24 26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
25 27 from apps.dds.forms import DDSConfigurationForm
26 28 from apps.jars.forms import JARSConfigurationForm
27 29 from apps.cgs.forms import CGSConfigurationForm
28 30 from apps.abs.forms import ABSConfigurationForm
29 31 from apps.usrp.forms import USRPConfigurationForm
30 32 from .utils import Params
31 33
32 34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
33 35 from apps.cgs.models import CGSConfiguration
34 36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
35 37 from apps.usrp.models import USRPConfiguration
36 38 from apps.abs.models import ABSConfiguration
37 39 from apps.rc.models import RCConfiguration, RCLine, RCLineType
38 40 from apps.dds.models import DDSConfiguration
39 41
40 42 from radarsys.celery import app
41 43
42 from django.contrib.auth.decorators import login_required
43 from django.contrib.auth.decorators import user_passes_test
44 from django.contrib.admin.views.decorators import staff_member_required
45 44
46 45 CONF_FORMS = {
47 46 'rc': RCConfigurationForm,
48 47 'dds': DDSConfigurationForm,
49 48 'jars': JARSConfigurationForm,
50 49 'cgs': CGSConfigurationForm,
51 50 'abs': ABSConfigurationForm,
52 51 'usrp': USRPConfigurationForm,
53 52 }
54 53
55 54 CONF_MODELS = {
56 55 'rc': RCConfiguration,
57 56 'dds': DDSConfiguration,
58 57 'jars': JARSConfiguration,
59 58 'cgs': CGSConfiguration,
60 59 'abs': ABSConfiguration,
61 60 'usrp': USRPConfiguration,
62 61 }
63 62
64 63 MIX_MODES = {
65 64 '0': 'P',
66 65 '1': 'S',
67 66 }
68 67
69 68 MIX_OPERATIONS = {
70 69 '0': 'OR',
71 70 '1': 'XOR',
72 71 '2': 'AND',
73 72 '3': 'NAND',
74 73 }
75 74
75
76 def is_developer(user):
77
78 groups = [str(g.name) for g in user.groups.all()]
79 return 'Developer' in groups or user.is_staff
80
81
82 def is_operator(user):
83
84 groups = [str(g.name) for g in user.groups.all()]
85 return 'Operator' in groups or user.is_staff
86
87
88 def has_been_modified(model):
89
90 prev_hash = model.hash
91 new_hash = hashlib.sha256(str(model.parms_to_dict)).hexdigest()
92 if prev_hash != new_hash:
93 model.hash = new_hash
94 model.save()
95 return True
96 return False
97
98
76 99 def index(request):
77 kwargs = {'no_sidebar':True}
100 kwargs = {'no_sidebar': True}
78 101
79 102 return render(request, 'index.html', kwargs)
80 103
81 104
82 105 def locations(request):
83 106
84 107 page = request.GET.get('page')
85 108 order = ('name',)
86 109
87 110 kwargs = get_paginator(Location, page, order)
88 111
89 112 kwargs['keys'] = ['name', 'description']
90 113 kwargs['title'] = 'Radar System'
91 114 kwargs['suptitle'] = 'List'
92 115 kwargs['no_sidebar'] = True
93 116
94 117 return render(request, 'base_list.html', kwargs)
95 118
96 119
97 120 def location(request, id_loc):
98 121
99 122 location = get_object_or_404(Location, pk=id_loc)
100 123
101 124 kwargs = {}
102 125 kwargs['location'] = location
103 126 kwargs['location_keys'] = ['name', 'description']
104 127
105 128 kwargs['title'] = 'Location'
106 129 kwargs['suptitle'] = 'Details'
107 130
108 131 return render(request, 'location.html', kwargs)
109 132
110 133
111 @user_passes_test(lambda u:u.is_staff)
134 @login_required
112 135 def location_new(request):
113 136
114 137 if request.method == 'GET':
115 138 form = LocationForm()
116 139
117 140 if request.method == 'POST':
118 141 form = LocationForm(request.POST)
119 142
120 143 if form.is_valid():
121 144 form.save()
122 145 return redirect('url_locations')
123 146
124 147 kwargs = {}
125 148 kwargs['form'] = form
126 149 kwargs['title'] = 'Radar System'
127 150 kwargs['suptitle'] = 'New'
128 151 kwargs['button'] = 'Create'
129 152
130 153 return render(request, 'base_edit.html', kwargs)
131 154
132 155
133 @user_passes_test(lambda u:u.is_staff)
156 @login_required
134 157 def location_edit(request, id_loc):
135 158
136 159 location = get_object_or_404(Location, pk=id_loc)
137 160
138 if request.method=='GET':
161 if request.method == 'GET':
139 162 form = LocationForm(instance=location)
140 163
141 if request.method=='POST':
164 if request.method == 'POST':
142 165 form = LocationForm(request.POST, instance=location)
143 166
144 167 if form.is_valid():
145 168 form.save()
146 169 return redirect('url_locations')
147 170
148 171 kwargs = {}
149 172 kwargs['form'] = form
150 173 kwargs['title'] = 'Location'
151 174 kwargs['suptitle'] = 'Edit'
152 175 kwargs['button'] = 'Update'
153 176
154 177 return render(request, 'base_edit.html', kwargs)
155 178
156 179
157 @user_passes_test(lambda u:u.is_staff)
180 @login_required
158 181 def location_delete(request, id_loc):
159 182
160 183 location = get_object_or_404(Location, pk=id_loc)
161 184
162 if request.method=='POST':
185 if request.method == 'POST':
163 186
164 187 if request.user.is_staff:
165 188 location.delete()
166 189 return redirect('url_locations')
167 190
168 191 messages.error(request, 'Not enough permission to delete this object')
169 192 return redirect(location.get_absolute_url())
170 193
171 194 kwargs = {
172 'title': 'Delete',
173 'suptitle': 'Location',
174 'object': location,
175 'previous': location.get_absolute_url(),
176 'delete': True
177 }
195 'title': 'Delete',
196 'suptitle': 'Location',
197 'object': location,
198 'delete': True
199 }
178 200
179 201 return render(request, 'confirm.html', kwargs)
180 202
181 203
182 204 def devices(request):
183 205
184 206 page = request.GET.get('page')
185 order = ('device_type', 'name')
207 order = ('location', 'device_type')
186 208
187 kwargs = get_paginator(Device, page, order)
188 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
209 filters = request.GET.copy()
210 kwargs = get_paginator(Device, page, order, filters)
211 form = FilterForm(initial=request.GET, extra_fields=['tags'])
212
213 kwargs['keys'] = ['device_type', 'location',
214 'ip_address', 'port_address', 'actions']
189 215 kwargs['title'] = 'Device'
190 216 kwargs['suptitle'] = 'List'
191 217 kwargs['no_sidebar'] = True
218 kwargs['form'] = form
219 kwargs['add_url'] = reverse('url_add_device')
220 filters.pop('page', None)
221 kwargs['q'] = urlencode(filters)
222 kwargs['menu'] = 'device'
192 223
193 224 return render(request, 'base_list.html', kwargs)
194 225
195 226
196 227 def device(request, id_dev):
197 228
198 229 device = get_object_or_404(Device, pk=id_dev)
199 230
200 231 kwargs = {}
201 232 kwargs['device'] = device
202 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
233 kwargs['device_keys'] = ['device_type',
234 'ip_address', 'port_address', 'description']
203 235
204 236 kwargs['title'] = 'Device'
205 237 kwargs['suptitle'] = 'Details'
206 238
207 239 return render(request, 'device.html', kwargs)
208 240
209 241
210 @user_passes_test(lambda u:u.is_staff)
242 @login_required
211 243 def device_new(request):
212 244
213 245 if request.method == 'GET':
214 246 form = DeviceForm()
215 247
216 248 if request.method == 'POST':
217 249 form = DeviceForm(request.POST)
218 250
219 251 if form.is_valid():
220 252 form.save()
221 253 return redirect('url_devices')
222 254
223 255 kwargs = {}
224 256 kwargs['form'] = form
225 257 kwargs['title'] = 'Device'
226 258 kwargs['suptitle'] = 'New'
227 259 kwargs['button'] = 'Create'
228 260
229 261 return render(request, 'base_edit.html', kwargs)
230 262
231 263
232 @user_passes_test(lambda u:u.is_staff)
264 @login_required
233 265 def device_edit(request, id_dev):
234 266
235 267 device = get_object_or_404(Device, pk=id_dev)
236 268
237 if request.method=='GET':
269 if request.method == 'GET':
238 270 form = DeviceForm(instance=device)
239 271
240 if request.method=='POST':
272 if request.method == 'POST':
241 273 form = DeviceForm(request.POST, instance=device)
242 274
243 275 if form.is_valid():
244 276 form.save()
245 277 return redirect(device.get_absolute_url())
246 278
247 279 kwargs = {}
248 280 kwargs['form'] = form
249 281 kwargs['title'] = 'Device'
250 282 kwargs['suptitle'] = 'Edit'
251 283 kwargs['button'] = 'Update'
252 284
253 285 return render(request, 'base_edit.html', kwargs)
254 286
255 287
256 @user_passes_test(lambda u:u.is_staff)
288 @login_required
257 289 def device_delete(request, id_dev):
258 290
259 291 device = get_object_or_404(Device, pk=id_dev)
260 292
261 if request.method=='POST':
293 if request.method == 'POST':
262 294
263 295 if request.user.is_staff:
264 296 device.delete()
265 297 return redirect('url_devices')
266 298
267 299 messages.error(request, 'Not enough permission to delete this object')
268 300 return redirect(device.get_absolute_url())
269 301
270 302 kwargs = {
271 'title': 'Delete',
272 'suptitle': 'Device',
273 'object': device,
274 'previous': device.get_absolute_url(),
275 'delete': True
276 }
303 'title': 'Delete',
304 'suptitle': 'Device',
305 'object': device,
306 'delete': True
307 }
277 308
278 309 return render(request, 'confirm.html', kwargs)
279 310
280 311
281 @user_passes_test(lambda u:u.is_staff)
312 @login_required
282 313 def device_change_ip(request, id_dev):
283 314
284 315 device = get_object_or_404(Device, pk=id_dev)
285 316
286 if request.method=='POST':
317 if request.method == 'POST':
287 318
288 319 if request.user.is_staff:
289 320 device.change_ip(**request.POST.dict())
290 321 level, message = device.message.split('|')
291 322 messages.add_message(request, level, message)
292 323 else:
293 messages.error(request, 'Not enough permission to delete this object')
324 messages.error(
325 request, 'Not enough permission to delete this object')
294 326 return redirect(device.get_absolute_url())
295 327
296 328 kwargs = {
297 'title': 'Device',
298 'suptitle': 'Change IP',
299 'object': device,
300 'previous': device.get_absolute_url(),
301 'form': ChangeIpForm(initial={'ip_address':device.ip_address}),
302 'message' : ' ',
303 }
329 'title': 'Device',
330 'suptitle': 'Change IP',
331 'object': device,
332 'previous': device.get_absolute_url(),
333 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
334 'message': ' ',
335 }
304 336
305 337 return render(request, 'confirm.html', kwargs)
306 338
307 339
308 340 def campaigns(request):
309 341
310 342 page = request.GET.get('page')
311 343 order = ('start_date',)
312 344 filters = request.GET.copy()
313 345
314 346 kwargs = get_paginator(Campaign, page, order, filters)
315 347
316 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
317 kwargs['keys'] = ['name', 'start_date', 'end_date']
348 form = FilterForm(initial=request.GET, extra_fields=[
349 'range_date', 'tags', 'template'])
350 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
318 351 kwargs['title'] = 'Campaign'
319 352 kwargs['suptitle'] = 'List'
320 353 kwargs['no_sidebar'] = True
321 354 kwargs['form'] = form
355 kwargs['add_url'] = reverse('url_add_campaign')
322 356 filters.pop('page', None)
323 357 kwargs['q'] = urlencode(filters)
324 358
325 359 return render(request, 'base_list.html', kwargs)
326 360
327 361
328 362 def campaign(request, id_camp):
329 363
330 364 campaign = get_object_or_404(Campaign, pk=id_camp)
331 365 experiments = Experiment.objects.filter(campaign=campaign)
332 366
333 367 form = CampaignForm(instance=campaign)
334 368
335 369 kwargs = {}
336 370 kwargs['campaign'] = campaign
337 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
371 kwargs['campaign_keys'] = ['template', 'name',
372 'start_date', 'end_date', 'tags', 'description']
338 373
339 374 kwargs['experiments'] = experiments
340 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
375 kwargs['experiment_keys'] = [
376 'name', 'radar_system', 'start_time', 'end_time']
341 377
342 378 kwargs['title'] = 'Campaign'
343 379 kwargs['suptitle'] = 'Details'
344 380
345 381 kwargs['form'] = form
346 382 kwargs['button'] = 'Add Experiment'
347 383
348 384 return render(request, 'campaign.html', kwargs)
349 385
350 386
351 @user_passes_test(lambda u:u.is_staff)
387 @login_required
352 388 def campaign_new(request):
353 389
354 390 kwargs = {}
355 391
356 392 if request.method == 'GET':
357 393
358 394 if 'template' in request.GET:
359 if request.GET['template']=='0':
360 form = NewForm(initial={'create_from':2},
395 if request.GET['template'] == '0':
396 form = NewForm(initial={'create_from': 2},
361 397 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
362 398 else:
363 399 kwargs['button'] = 'Create'
364 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
400 kwargs['experiments'] = Configuration.objects.filter(
401 experiment=request.GET['template'])
365 402 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
366 403 camp = Campaign.objects.get(pk=request.GET['template'])
367 404 form = CampaignForm(instance=camp,
368 initial={'name':'{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
369 'template':False})
405 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
406 'template': False})
370 407 elif 'blank' in request.GET:
371 408 kwargs['button'] = 'Create'
372 409 form = CampaignForm()
373 410 else:
374 411 form = NewForm()
375 412
376 413 if request.method == 'POST':
377 414 kwargs['button'] = 'Create'
378 415 post = request.POST.copy()
379 416 experiments = []
380 417
381 418 for id_exp in post.getlist('experiments'):
382 419 exp = Experiment.objects.get(pk=id_exp)
383 420 new_exp = exp.clone(template=False)
384 421 experiments.append(new_exp)
385 422
386 423 post.setlist('experiments', [])
387 424
388 425 form = CampaignForm(post)
389 426
390 427 if form.is_valid():
391 campaign = form.save()
428 campaign = form.save(commit=False)
429 campaign.author = request.user
392 430 for exp in experiments:
393 431 campaign.experiments.add(exp)
394 432 campaign.save()
395 433 return redirect('url_campaign', id_camp=campaign.id)
396 434
397 435 kwargs['form'] = form
398 436 kwargs['title'] = 'Campaign'
399 437 kwargs['suptitle'] = 'New'
400 438
401 439 return render(request, 'campaign_edit.html', kwargs)
402 440
403 441
404 @user_passes_test(lambda u:u.is_staff)
442 @login_required
405 443 def campaign_edit(request, id_camp):
406 444
407 445 campaign = get_object_or_404(Campaign, pk=id_camp)
408 446
409 if request.method=='GET':
447 if request.method == 'GET':
410 448 form = CampaignForm(instance=campaign)
411 449
412 if request.method=='POST':
450 if request.method == 'POST':
413 451 exps = campaign.experiments.all().values_list('pk', flat=True)
414 452 post = request.POST.copy()
415 453 new_exps = post.getlist('experiments')
416 454 post.setlist('experiments', [])
417 455 form = CampaignForm(post, instance=campaign)
418 456
419 457 if form.is_valid():
420 458 camp = form.save()
421 459 for id_exp in new_exps:
422 460 if int(id_exp) in exps:
423 461 exps.pop(id_exp)
424 462 else:
425 463 exp = Experiment.objects.get(pk=id_exp)
426 464 if exp.template:
427 465 camp.experiments.add(exp.clone(template=False))
428 466 else:
429 467 camp.experiments.add(exp)
430 468
431 469 for id_exp in exps:
432 470 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
433 471
434 472 return redirect('url_campaign', id_camp=id_camp)
435 473
436 474 kwargs = {}
437 475 kwargs['form'] = form
438 476 kwargs['title'] = 'Campaign'
439 477 kwargs['suptitle'] = 'Edit'
440 478 kwargs['button'] = 'Update'
441 479
442 480 return render(request, 'campaign_edit.html', kwargs)
443 481
444 482
445 @user_passes_test(lambda u:u.is_staff)
483 @login_required
446 484 def campaign_delete(request, id_camp):
447 485
448 486 campaign = get_object_or_404(Campaign, pk=id_camp)
449 487
450 if request.method=='POST':
488 if request.method == 'POST':
451 489 if request.user.is_staff:
452 490
453 491 for exp in campaign.experiments.all():
454 492 for conf in Configuration.objects.filter(experiment=exp):
455 493 conf.delete()
456 494 exp.delete()
457 495 campaign.delete()
458 496
459 497 return redirect('url_campaigns')
460 498
461 499 messages.error(request, 'Not enough permission to delete this object')
462 500 return redirect(campaign.get_absolute_url())
463 501
464 502 kwargs = {
465 'title': 'Delete',
466 'suptitle': 'Campaign',
467 'object': campaign,
468 'previous': campaign.get_absolute_url(),
469 'delete': True
470 }
503 'title': 'Delete',
504 'suptitle': 'Campaign',
505 'object': campaign,
506 'delete': True
507 }
471 508
472 509 return render(request, 'confirm.html', kwargs)
473 510
474 511
475 @user_passes_test(lambda u:u.is_staff)
512 @login_required
476 513 def campaign_export(request, id_camp):
477 514
478 515 campaign = get_object_or_404(Campaign, pk=id_camp)
479 516 content = campaign.parms_to_dict()
480 517 content_type = 'application/json'
481 filename = '%s_%s.json' %(campaign.name, campaign.id)
518 filename = '%s_%s.json' % (campaign.name, campaign.id)
482 519
483 520 response = HttpResponse(content_type=content_type)
484 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
521 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
485 522 response.write(json.dumps(content, indent=2))
486 523
487 524 return response
488 525
489 526
490 @user_passes_test(lambda u:u.is_staff)
527 @login_required
491 528 def campaign_import(request, id_camp):
492 529
493 530 campaign = get_object_or_404(Campaign, pk=id_camp)
494 531
495 532 if request.method == 'GET':
496 533 file_form = UploadFileForm()
497 534
498 535 if request.method == 'POST':
499 536 file_form = UploadFileForm(request.POST, request.FILES)
500 537
501 538 if file_form.is_valid():
502 new_camp = campaign.dict_to_parms(json.load(request.FILES['file']), CONF_MODELS)
503 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
539 new_camp = campaign.dict_to_parms(
540 json.load(request.FILES['file']), CONF_MODELS)
541 messages.success(
542 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
504 543 return redirect(new_camp.get_absolute_url_edit())
505 544
506 545 messages.error(request, "Could not import parameters from file")
507 546
508 547 kwargs = {}
509 548 kwargs['title'] = 'Campaign'
510 549 kwargs['form'] = file_form
511 550 kwargs['suptitle'] = 'Importing file'
512 551 kwargs['button'] = 'Import'
513 552
514 553 return render(request, 'campaign_import.html', kwargs)
515 554
516 555
517 556 def experiments(request):
518 557
519 558 page = request.GET.get('page')
520 559 order = ('location',)
521 560 filters = request.GET.copy()
522 561
562 if 'my experiments' in filters:
563 filters.pop('my experiments', None)
564 filters['mine'] = request.user.id
565
523 566 kwargs = get_paginator(Experiment, page, order, filters)
524 567
525 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
568 fields = ['tags', 'template']
569 if request.user.is_authenticated:
570 fields.append('my experiments')
526 571
527 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
572 form = FilterForm(initial=request.GET, extra_fields=fields)
573
574 kwargs['keys'] = ['name', 'radar_system',
575 'start_time', 'end_time', 'actions']
528 576 kwargs['title'] = 'Experiment'
529 577 kwargs['suptitle'] = 'List'
530 578 kwargs['no_sidebar'] = True
531 579 kwargs['form'] = form
580 kwargs['add_url'] = reverse('url_add_experiment')
581 filters = request.GET.copy()
532 582 filters.pop('page', None)
533 583 kwargs['q'] = urlencode(filters)
534 584
535 585 return render(request, 'base_list.html', kwargs)
536 586
537 587
538 588 def experiment(request, id_exp):
539 589
540 590 experiment = get_object_or_404(Experiment, pk=id_exp)
541 591
542 configurations = Configuration.objects.filter(experiment=experiment, type=0)
592 configurations = Configuration.objects.filter(
593 experiment=experiment, type=0)
543 594
544 595 kwargs = {}
545 596
546 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'freq', 'start_time', 'end_time']
597 kwargs['experiment_keys'] = ['template', 'radar_system',
598 'name', 'freq', 'start_time', 'end_time']
547 599 kwargs['experiment'] = experiment
548 600
549 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
601 kwargs['configuration_keys'] = ['name', 'device__ip_address',
602 'device__port_address', 'device__status']
550 603 kwargs['configurations'] = configurations
551 604
552 605 kwargs['title'] = 'Experiment'
553 606 kwargs['suptitle'] = 'Details'
554 607
555 608 kwargs['button'] = 'Add Configuration'
556 609
557 610 ###### SIDEBAR ######
558 611 kwargs.update(sidebar(experiment=experiment))
559 612
560 613 return render(request, 'experiment.html', kwargs)
561 614
562 615
563 @user_passes_test(lambda u:u.is_staff)
616 @login_required
564 617 def experiment_new(request, id_camp=None):
565 618
619 if not is_developer(request.user):
620 messages.error(
621 request, 'Developer required, to create new Experiments')
622 return redirect('index')
566 623 kwargs = {}
567 624
568 625 if request.method == 'GET':
569 626 if 'template' in request.GET:
570 if request.GET['template']=='0':
571 form = NewForm(initial={'create_from':2},
627 if request.GET['template'] == '0':
628 form = NewForm(initial={'create_from': 2},
572 629 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
573 630 else:
574 631 kwargs['button'] = 'Create'
575 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
576 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
577 exp=Experiment.objects.get(pk=request.GET['template'])
632 kwargs['configurations'] = Configuration.objects.filter(
633 experiment=request.GET['template'])
634 kwargs['configuration_keys'] = ['name', 'device__name',
635 'device__ip_address', 'device__port_address']
636 exp = Experiment.objects.get(pk=request.GET['template'])
578 637 form = ExperimentForm(instance=exp,
579 638 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
580 639 'template': False})
581 640 elif 'blank' in request.GET:
582 641 kwargs['button'] = 'Create'
583 642 form = ExperimentForm()
584 643 else:
585 644 form = NewForm()
586 645
587 646 if request.method == 'POST':
588 647 form = ExperimentForm(request.POST)
589 648 if form.is_valid():
590 experiment = form.save()
649 experiment = form.save(commit=False)
650 experiment.author = request.user
651 experiment.save()
591 652
592 653 if 'template' in request.GET:
593 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
654 configurations = Configuration.objects.filter(
655 experiment=request.GET['template'], type=0)
594 656 for conf in configurations:
595 657 conf.clone(experiment=experiment, template=False)
596 658
597 659 return redirect('url_experiment', id_exp=experiment.id)
598 660
599 661 kwargs['form'] = form
600 662 kwargs['title'] = 'Experiment'
601 663 kwargs['suptitle'] = 'New'
602 664
603 665 return render(request, 'experiment_edit.html', kwargs)
604 666
605 667
606 @user_passes_test(lambda u:u.is_staff)
668 @login_required
607 669 def experiment_edit(request, id_exp):
608 670
609 671 experiment = get_object_or_404(Experiment, pk=id_exp)
610 672
611 673 if request.method == 'GET':
612 674 form = ExperimentForm(instance=experiment)
613 675
614 if request.method=='POST':
676 if request.method == 'POST':
615 677 form = ExperimentForm(request.POST, instance=experiment)
616 678
617 679 if form.is_valid():
618 680 experiment = form.save()
619 681 return redirect('url_experiment', id_exp=experiment.id)
620 682
621 683 kwargs = {}
622 684 kwargs['form'] = form
623 685 kwargs['title'] = 'Experiment'
624 686 kwargs['suptitle'] = 'Edit'
625 687 kwargs['button'] = 'Update'
626 688
627 689 return render(request, 'experiment_edit.html', kwargs)
628 690
629 691
630 @user_passes_test(lambda u:u.is_staff)
692 @login_required
631 693 def experiment_delete(request, id_exp):
632 694
633 695 experiment = get_object_or_404(Experiment, pk=id_exp)
634 696
635 if request.method=='POST':
697 if request.method == 'POST':
636 698 if request.user.is_staff:
637 699 for conf in Configuration.objects.filter(experiment=experiment):
638 700 conf.delete()
639 701 experiment.delete()
640 702 return redirect('url_experiments')
641 703
642 704 messages.error(request, 'Not enough permission to delete this object')
643 705 return redirect(experiment.get_absolute_url())
644 706
645 707 kwargs = {
646 'title': 'Delete',
647 'suptitle': 'Experiment',
648 'object': experiment,
649 'previous': experiment.get_absolute_url(),
650 'delete': True
651 }
708 'title': 'Delete',
709 'suptitle': 'Experiment',
710 'object': experiment,
711 'delete': True
712 }
652 713
653 714 return render(request, 'confirm.html', kwargs)
654 715
655 716
656 @user_passes_test(lambda u:u.is_staff)
717 @login_required
657 718 def experiment_export(request, id_exp):
658 719
659 720 experiment = get_object_or_404(Experiment, pk=id_exp)
660 721 content = experiment.parms_to_dict()
661 722 content_type = 'application/json'
662 filename = '%s_%s.json' %(experiment.name, experiment.id)
723 filename = '%s_%s.json' % (experiment.name, experiment.id)
663 724
664 725 response = HttpResponse(content_type=content_type)
665 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
726 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
666 727 response.write(json.dumps(content, indent=2))
667 728
668 729 return response
669 730
670 731
671 @user_passes_test(lambda u:u.is_staff)
732 @login_required
672 733 def experiment_import(request, id_exp):
673 734
674 experiment = get_object_or_404(Experiment, pk=id_exp)
735 experiment = get_object_or_404(Experiment, pk=id_exp)
675 736 configurations = Configuration.objects.filter(experiment=experiment)
676 737
677 738 if request.method == 'GET':
678 739 file_form = UploadFileForm()
679 740
680 741 if request.method == 'POST':
681 742 file_form = UploadFileForm(request.POST, request.FILES)
682 743
683 744 if file_form.is_valid():
684 new_exp = experiment.dict_to_parms(json.load(request.FILES['file']), CONF_MODELS)
685 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
745 new_exp = experiment.dict_to_parms(
746 json.load(request.FILES['file']), CONF_MODELS)
747 messages.success(
748 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
686 749 return redirect(new_exp.get_absolute_url_edit())
687 750
688 751 messages.error(request, "Could not import parameters from file")
689 752
690 753 kwargs = {}
691 754 kwargs['title'] = 'Experiment'
692 755 kwargs['form'] = file_form
693 756 kwargs['suptitle'] = 'Importing file'
694 757 kwargs['button'] = 'Import'
695 758
696 759 kwargs.update(sidebar(experiment=experiment))
697 760
698 761 return render(request, 'experiment_import.html', kwargs)
699 762
700 763
701 @user_passes_test(lambda u:u.is_staff)
764 @login_required
702 765 def experiment_start(request, id_exp):
703 766
704 767 exp = get_object_or_404(Experiment, pk=id_exp)
705 768
706 769 if exp.status == 2:
707 770 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
708 771 else:
709 772 exp.status = exp.start()
710 if exp.status==0:
773 if exp.status == 0:
711 774 messages.error(request, 'Experiment {} not start'.format(exp))
712 if exp.status==2:
775 if exp.status == 2:
713 776 messages.success(request, 'Experiment {} started'.format(exp))
714 777
715 778 exp.save()
716 779
717 780 return redirect(exp.get_absolute_url())
718 781
719 782
720 @user_passes_test(lambda u:u.is_staff)
783 @login_required
721 784 def experiment_stop(request, id_exp):
722 785
723 786 exp = get_object_or_404(Experiment, pk=id_exp)
724 787
725 788 if exp.status == 2:
726 789 exp.status = exp.stop()
727 790 exp.save()
728 791 messages.success(request, 'Experiment {} stopped'.format(exp))
729 792 else:
730 793 messages.error(request, 'Experiment {} not running'.format(exp))
731 794
732 795 return redirect(exp.get_absolute_url())
733 796
734 797
735 798 def experiment_status(request, id_exp):
736 799
737 800 exp = get_object_or_404(Experiment, pk=id_exp)
738 801
739 802 exp.get_status()
740 803
741 804 return redirect(exp.get_absolute_url())
742 805
743 806
744 @user_passes_test(lambda u:u.is_staff)
807 @login_required
745 808 def experiment_mix(request, id_exp):
746 809
747 810 experiment = get_object_or_404(Experiment, pk=id_exp)
748 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
749 mix=False)]
750
751 if len(rc_confs)<2:
752 messages.warning(request, 'You need at least two RC Configurations to make a mix')
811 rc_confs = [conf for conf in RCConfiguration.objects.filter(
812 experiment=id_exp,
813 type=0,
814 mix=False)]
815
816 if len(rc_confs) < 2:
817 messages.warning(
818 request, 'You need at least two RC Configurations to make a mix')
753 819 return redirect(experiment.get_absolute_url())
754 820
755 821 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
756 822
757 823 if mix_confs:
758 824 mix = mix_confs[0]
759 825 else:
760 826 mix = RCConfiguration(experiment=experiment,
761 827 device=rc_confs[0].device,
762 828 ipp=rc_confs[0].ipp,
763 829 clock_in=rc_confs[0].clock_in,
764 830 clock_divider=rc_confs[0].clock_divider,
765 831 mix=True,
766 832 parameters='')
767 833 mix.save()
768 834
769 835 line_type = RCLineType.objects.get(name='mix')
770 836 for i in range(len(rc_confs[0].get_lines())):
771 837 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
772 838 line.save()
773 839
774 840 initial = {'name': mix.name,
775 841 'result': parse_mix_result(mix.parameters),
776 842 'delay': 0,
777 'mask': [0,1,2,3,4,5,6,7]
843 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
778 844 }
779 845
780 if request.method=='GET':
846 if request.method == 'GET':
781 847 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
782 848
783 if request.method=='POST':
849 if request.method == 'POST':
784 850 result = mix.parameters
785 851
786 852 if '{}|'.format(request.POST['experiment']) in result:
787 853 messages.error(request, 'Configuration already added')
788 854 else:
789 855 if 'operation' in request.POST:
790 856 operation = MIX_OPERATIONS[request.POST['operation']]
791 857 else:
792 858 operation = ' '
793 859
794 860 mode = MIX_MODES[request.POST['mode']]
795 861
796 862 if result:
797 863 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
798 request.POST['experiment'],
799 mode,
800 operation,
801 float(request.POST['delay']),
802 parse_mask(request.POST.getlist('mask'))
803 )
864 request.POST['experiment'],
865 mode,
866 operation,
867 float(
868 request.POST['delay']),
869 parse_mask(
870 request.POST.getlist('mask'))
871 )
804 872 else:
805 873 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
806 mode,
807 operation,
808 float(request.POST['delay']),
809 parse_mask(request.POST.getlist('mask'))
810 )
874 mode,
875 operation,
876 float(request.POST['delay']),
877 parse_mask(
878 request.POST.getlist('mask'))
879 )
811 880
812 881 mix.parameters = result
813 mix.name = request.POST['name']
814 882 mix.save()
815 883 mix.update_pulses()
816 884
817 885 initial['result'] = parse_mix_result(result)
818 886 initial['name'] = mix.name
819 887
820 888 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
821 889
822
823 890 kwargs = {
824 'title': 'Experiment',
825 'suptitle': 'Mix Configurations',
826 'form' : form,
827 'extra_button': 'Delete',
828 'button': 'Add',
829 'cancel': 'Back',
830 'previous': experiment.get_absolute_url(),
831 'id_exp':id_exp,
891 'title': 'Experiment',
892 'suptitle': 'Mix Configurations',
893 'form': form,
894 'extra_button': 'Delete',
895 'button': 'Add',
896 'cancel': 'Back',
897 'previous': experiment.get_absolute_url(),
898 'id_exp': id_exp,
832 899
833 }
900 }
834 901
835 902 return render(request, 'experiment_mix.html', kwargs)
836 903
837 904
838 @user_passes_test(lambda u:u.is_staff)
905 @login_required
839 906 def experiment_mix_delete(request, id_exp):
840 907
841 908 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
842 909 values = conf.parameters.split('-')
843 910 conf.parameters = '-'.join(values[:-1])
844 911 conf.save()
845 912
846 913 return redirect('url_mix_experiment', id_exp=id_exp)
847 914
848 915
849 916 def experiment_summary(request, id_exp):
850 917
851 experiment = get_object_or_404(Experiment, pk=id_exp)
852 configurations = Configuration.objects.filter(experiment=experiment, type=0)
918 experiment = get_object_or_404(Experiment, pk=id_exp)
919 configurations = Configuration.objects.filter(
920 experiment=experiment, type=0)
853 921
854 922 kwargs = {}
855
856 kwargs['experiment_keys'] = ['radar_system', 'name', 'freq', 'start_time', 'end_time']
923 kwargs['experiment_keys'] = ['radar_system',
924 'name', 'freq', 'start_time', 'end_time']
857 925 kwargs['experiment'] = experiment
858
859 926 kwargs['configurations'] = []
860
861 927 kwargs['title'] = 'Experiment Summary'
862 928 kwargs['suptitle'] = 'Details'
863
864 929 kwargs['button'] = 'Verify Parameters'
865 930
866 c_vel = 3.0*(10**8) #m/s
867 ope_freq = experiment.freq*(10**6) #1/s
868 radar_lambda = c_vel/ope_freq #m
931 c_vel = 3.0*(10**8) # m/s
932 ope_freq = experiment.freq*(10**6) # 1/s
933 radar_lambda = c_vel/ope_freq # m
869 934 kwargs['radar_lambda'] = radar_lambda
870 935
871 jars_conf = False
872 rc_conf = False
936 ipp = None
937 nsa = 1
873 938 code_id = 0
874 939 tx_line = {}
875 940
876 for configuration in configurations:
877
878 #--------------------- RC ----------------------:
879 if configuration.device.device_type.name == 'rc':
880 if configuration.mix:
881 continue
882 rc_conf = True
883 ipp = configuration.ipp
884 lines = configuration.get_lines(line_type__name='tx')
885 configuration.tx_lines = []
886
887 for tx_line in lines:
888 if tx_line.get_name()[-1] == 'A':
889 txa_line = tx_line
890 txa_params = json.loads(txa_line.params)
891 line = {'name':tx_line.get_name()}
892 tx_params = json.loads(tx_line.params)
893 line['width'] = tx_params['pulse_width']
894 if line['width'] in (0, '0'):
895 continue
896 delays = tx_params['delays']
897
898 if delays not in ('', '0'):
899 n = len(delays.split(','))
900 line['taus'] = '{} Taus: {}'.format(n, delays)
901 else:
902 line['taus'] = '-'
903
904 for code_line in configuration.get_lines(line_type__name='codes'):
905 code_params = json.loads(code_line.params)
906 code_id = code_params['code']
907 if tx_line.pk==int(code_params['TX_ref']):
908 line['codes'] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
909 '-'.join(code_params['codes']))
910
911 for windows_line in configuration.get_lines(line_type__name='windows'):
912 win_params = json.loads(windows_line.params)
913 if tx_line.pk==int(win_params['TX_ref']):
914 windows = ''
915 nsa = win_params['params'][0]['number_of_samples']
916 for i, params in enumerate(win_params['params']):
917 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(i, **params)
918 line['windows'] = mark_safe(windows)
919
920 configuration.tx_lines.append(line)
921
922 if txa_line:
923 kwargs['duty_cycle'] = float(txa_params['pulse_width'])/ipp*100
924
925 #-------------------- JARS -----------------------:
926 if configuration.device.device_type.name == 'jars':
927 jars_conf = True
928 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
929 channels_number = configuration.channels_number
930 exp_type = configuration.exp_type
931 fftpoints = configuration.fftpoints
932 filter_parms = configuration.filter_parms
933 filter_parms = ast.literal_eval(filter_parms)
934 spectral_number = configuration.spectral_number
935 acq_profiles = configuration.acq_profiles
936 cohe_integr = configuration.cohe_integr
937 profiles_block = configuration.profiles_block
938
939 if filter_parms.__class__.__name__=='str':
940 filter_parms = eval(filter_parms)
941
942 kwargs['configurations'].append(configuration)
943
944
945 #------ RC & JARS ------:
946 if rc_conf and jars_conf:
947 #RC filter values:
948
949 if exp_type == 0: #Short
950 bytes_ = 2
951 b = nsa*2*bytes_*channels_number
952 else: #Float
953 bytes_ = 4
954 channels = channels_number + spectral_number
955 b = nsa*2*bytes_*fftpoints*channels
941 for configuration in configurations.filter(device__device_type__name = 'rc'):
956 942
943 if configuration.mix:
944 continue
945 conf = {'conf': configuration}
946 conf['keys'] = []
947 conf['NTxs'] = configuration.ntx
948 conf['keys'].append('NTxs')
949 ipp = configuration.ipp
950 conf['IPP'] = ipp
951 conf['keys'].append('IPP')
952 lines = configuration.get_lines(line_type__name='tx')
953
954 for tx_line in lines:
955 tx_params = json.loads(tx_line.params)
956 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
957 conf['keys'].append(tx_line.get_name())
958 delays = tx_params['delays']
959 if delays not in ('', '0'):
960 n = len(delays.split(','))
961 taus = '{} Taus: {}'.format(n, delays)
962 else:
963 taus = '-'
964 conf['Taus ({})'.format(tx_line.get_name())] = taus
965 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
966 for code_line in configuration.get_lines(line_type__name='codes'):
967 code_params = json.loads(code_line.params)
968 code_id = code_params['code']
969 if tx_line.pk == int(code_params['TX_ref']):
970 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
971 '-'.join(code_params['codes']))
972 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
973
974 for windows_line in configuration.get_lines(line_type__name='windows'):
975 win_params = json.loads(windows_line.params)
976 if tx_line.pk == int(win_params['TX_ref']):
977 windows = ''
978 nsa = win_params['params'][0]['number_of_samples']
979 for i, params in enumerate(win_params['params']):
980 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
981 i, **params)
982 conf['Window'] = mark_safe(windows)
983 conf['keys'].append('Window')
984
985 kwargs['configurations'].append(conf)
986
987 for configuration in configurations.filter(device__device_type__name = 'jars'):
988
989 conf = {'conf': configuration}
990 conf['keys'] = []
991 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
992 conf['keys'].append('Type of Data')
993 channels_number = configuration.channels_number
994 exp_type = configuration.exp_type
995 fftpoints = configuration.fftpoints
996 filter_parms = json.loads(configuration.filter_parms)
997 spectral_number = configuration.spectral_number
998 acq_profiles = configuration.acq_profiles
999 cohe_integr = configuration.cohe_integr
1000 profiles_block = configuration.profiles_block
1001
1002 conf['Num of Profiles'] = acq_profiles
1003 conf['keys'].append('Num of Profiles')
1004
1005 conf['Prof per Block'] = profiles_block
1006 conf['keys'].append('Prof per Block')
1007
1008 conf['Blocks per File'] = configuration.raw_data_blocks
1009 conf['keys'].append('Blocks per File')
1010
1011 if exp_type == 0: # Short
1012 bytes_ = 2
1013 b = nsa*2*bytes_*channels_number
1014 else: # Float
1015 bytes_ = 4
1016 channels = channels_number + spectral_number
1017 b = nsa*2*bytes_*fftpoints*channels
1018
1019 codes_num = 7
1020 if code_id == 2:
957 1021 codes_num = 7
958 if code_id == 2:
959 codes_num = 7
960 elif code_id == 12:
961 codes_num = 15
962
963 #Jars filter values:
964 try:
965 clock = eval(filter_parms['clock'])
966 filter_2 = eval(filter_parms['filter_2'])
967 filter_5 = eval(filter_parms['filter_5'])
968 filter_fir = eval(filter_parms['filter_fir'])
969 except:
970 clock = float(filter_parms['clock'])
971 filter_2 = int(filter_parms['filter_2'])
972 filter_5 = int(filter_parms['filter_5'])
973 filter_fir = int(filter_parms['filter_fir'])
974 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
975
976 #Jars values:
977 IPP_units = ipp/0.15*Fs_MHz
978 IPP_us = IPP_units / Fs_MHz
979 IPP_s = IPP_units / (Fs_MHz * (10**6))
980 Ts = 1/(Fs_MHz*(10**6))
981
982 #Values
983 Va = radar_lambda/(4*Ts*cohe_integr)
984 rate_bh = ((nsa-codes_num)*channels_number*2*bytes_/IPP_us)*(36*(10**8)/cohe_integr)
985 rate_gh = rate_bh/(1024*1024*1024)
986 kwargs['rate_bh'] = str(rate_bh) + " (Bytes/h)"
987 kwargs['rate_gh'] = str(rate_gh)+" (GBytes/h)"
988 kwargs['va'] = Va
989 kwargs['time_per_block'] = IPP_s * profiles_block * cohe_integr
990 kwargs['acqtime'] = IPP_s * acq_profiles
991 kwargs['vrange'] = 3/(2*IPP_s*cohe_integr)
992
993 else:
994 kwargs['rate_bh'] = ''
995 kwargs['rate_gh'] = ''
996 kwargs['va'] = ''
997 kwargs['time_per_block'] = ''
998 kwargs['acqtime'] = ''
999 kwargs['vrange'] = ''
1022 elif code_id == 12:
1023 codes_num = 15
1024
1025 #Jars filter values:
1026
1027 clock = float(filter_parms['clock'])
1028 filter_2 = int(filter_parms['cic_2'])
1029 filter_5 = int(filter_parms['cic_5'])
1030 filter_fir = int(filter_parms['fir'])
1031 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1032
1033 #Jars values:
1034 if ipp is not None:
1035 IPP_units = ipp/0.15*Fs_MHz
1036 IPP_us = IPP_units / Fs_MHz
1037 IPP_s = IPP_units / (Fs_MHz * (10**6))
1038 Ts = 1/(Fs_MHz*(10**6))
1039
1040 Va = radar_lambda/(4*Ts*cohe_integr)
1041 rate_bh = ((nsa-codes_num)*channels_number*2 *
1042 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1043 rate_gh = rate_bh/(1024*1024*1024)
1044
1045 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1046 conf['keys'].append('Time per Block')
1047 conf['Acq time'] = IPP_s * acq_profiles
1048 conf['keys'].append('Acq time')
1049 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1050 conf['keys'].append('Data rate')
1051 conf['Va (m/s)'] = Va
1052 conf['keys'].append('Va (m/s)')
1053 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1054 conf['keys'].append('Vrange (m/s)')
1055
1056 kwargs['configurations'].append(conf)
1000 1057
1001 1058 ###### SIDEBAR ######
1002 1059 kwargs.update(sidebar(experiment=experiment))
1003 1060
1004 1061 return render(request, 'experiment_summary.html', kwargs)
1005 1062
1006 1063
1007 @user_passes_test(lambda u:u.is_staff)
1064 @login_required
1008 1065 def experiment_verify(request, id_exp):
1009 1066
1010 experiment = get_object_or_404(Experiment, pk=id_exp)
1067 experiment = get_object_or_404(Experiment, pk=id_exp)
1011 1068 experiment_data = experiment.parms_to_dict()
1012 configurations = Configuration.objects.filter(experiment=experiment, type=0)
1069 configurations = Configuration.objects.filter(
1070 experiment=experiment, type=0)
1013 1071
1014 1072 kwargs = {}
1015 1073
1016 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
1074 kwargs['experiment_keys'] = ['template',
1075 'radar_system', 'name', 'start_time', 'end_time']
1017 1076 kwargs['experiment'] = experiment
1018 1077
1019 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
1078 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1079 'device__port_address', 'device__status']
1020 1080 kwargs['configurations'] = configurations
1021 1081 kwargs['experiment_data'] = experiment_data
1022 1082
1023 1083 kwargs['title'] = 'Verify Experiment'
1024 1084 kwargs['suptitle'] = 'Parameters'
1025 1085
1026 1086 kwargs['button'] = 'Update'
1027 1087
1028 1088 jars_conf = False
1029 rc_conf = False
1030 dds_conf = False
1089 rc_conf = False
1090 dds_conf = False
1031 1091
1032 1092 for configuration in configurations:
1033 1093 #-------------------- JARS -----------------------:
1034 1094 if configuration.device.device_type.name == 'jars':
1035 1095 jars_conf = True
1036 1096 jars = configuration
1037 kwargs['jars_conf'] = jars_conf
1038 filter_parms = jars.filter_parms
1039 filter_parms = ast.literal_eval(filter_parms)
1097 kwargs['jars_conf'] = jars_conf
1098 filter_parms = json.loads(jars.filter_parms)
1040 1099 kwargs['filter_parms'] = filter_parms
1041 1100 #--Sampling Frequency
1042 clock = eval(filter_parms['clock'])
1043 filter_2 = eval(filter_parms['filter_2'])
1044 filter_5 = eval(filter_parms['filter_5'])
1045 filter_fir = eval(filter_parms['filter_fir'])
1101 clock = filter_parms['clock']
1102 filter_2 = filter_parms['cic_2']
1103 filter_5 = filter_parms['cic_5']
1104 filter_fir = filter_parms['fir']
1046 1105 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1047 1106
1048 1107 kwargs['samp_freq_jars'] = samp_freq_jars
1049 kwargs['jars'] = configuration
1108 kwargs['jars'] = configuration
1050 1109
1051 1110 #--------------------- RC ----------------------:
1052 1111 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1053 1112 rc_conf = True
1054 1113 rc = configuration
1055 1114
1056 1115 rc_parms = configuration.parms_to_dict()
1057 1116
1058 1117 win_lines = rc.get_lines(line_type__name='windows')
1059 1118 if win_lines:
1060 1119 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1061 1120 #--Sampling Frequency
1062 1121 samp_freq_rc = 0.15/dh
1063 1122 kwargs['samp_freq_rc'] = samp_freq_rc
1064 1123
1065 1124 kwargs['rc_conf'] = rc_conf
1066 kwargs['rc'] = configuration
1125 kwargs['rc'] = configuration
1067 1126
1068 1127 #-------------------- DDS ----------------------:
1069 1128 if configuration.device.device_type.name == 'dds':
1070 1129 dds_conf = True
1071 1130 dds = configuration
1072 1131 dds_parms = configuration.parms_to_dict()
1073 1132
1074 1133 kwargs['dds_conf'] = dds_conf
1075 kwargs['dds'] = configuration
1076
1134 kwargs['dds'] = configuration
1077 1135
1078 1136 #------------Validation------------:
1079 1137 #Clock
1080 1138 if dds_conf and rc_conf and jars_conf:
1081 1139 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1082 1140 messages.warning(request, "Devices don't have the same clock.")
1083 1141 elif rc_conf and jars_conf:
1084 1142 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1085 1143 messages.warning(request, "Devices don't have the same clock.")
1086 1144 elif rc_conf and dds_conf:
1087 1145 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1088 1146 messages.warning(request, "Devices don't have the same clock.")
1089 1147 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1090 messages.warning(request, "Devices don't have the same Frequency A.")
1091
1148 messages.warning(
1149 request, "Devices don't have the same Frequency A.")
1092 1150
1093 1151 #------------POST METHOD------------:
1094 1152 if request.method == 'POST':
1095 1153 if request.POST['suggest_clock']:
1096 1154 try:
1097 1155 suggest_clock = float(request.POST['suggest_clock'])
1098 1156 except:
1099 1157 messages.warning(request, "Invalid value in CLOCK IN.")
1100 1158 return redirect('url_verify_experiment', id_exp=experiment.id)
1101 1159 else:
1102 1160 suggest_clock = ""
1103 1161 if suggest_clock:
1104 1162 if rc_conf:
1105 1163 rc.clock_in = suggest_clock
1106 1164 rc.save()
1107 1165 if jars_conf:
1108 filter_parms = jars.filter_parms
1109 filter_parms = ast.literal_eval(filter_parms)
1166 filter_parms = jars.filter_parms
1167 filter_parms = ast.literal_eval(filter_parms)
1110 1168 filter_parms['clock'] = suggest_clock
1111 1169 jars.filter_parms = json.dumps(filter_parms)
1112 1170 jars.save()
1113 1171 kwargs['filter_parms'] = filter_parms
1114 1172 if dds_conf:
1115 1173 dds.clock = suggest_clock
1116 1174 dds.save()
1117 1175
1118 1176 if request.POST['suggest_frequencyA']:
1119 1177 try:
1120 1178 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1121 1179 except:
1122 1180 messages.warning(request, "Invalid value in FREQUENCY A.")
1123 1181 return redirect('url_verify_experiment', id_exp=experiment.id)
1124 1182 else:
1125 1183 suggest_frequencyA = ""
1126 1184 if suggest_frequencyA:
1127 1185 if jars_conf:
1128 filter_parms = jars.filter_parms
1129 filter_parms = ast.literal_eval(filter_parms)
1186 filter_parms = jars.filter_parms
1187 filter_parms = ast.literal_eval(filter_parms)
1130 1188 filter_parms['fch'] = suggest_frequencyA
1131 1189 jars.filter_parms = json.dumps(filter_parms)
1132 1190 jars.save()
1133 1191 kwargs['filter_parms'] = filter_parms
1134 1192 if dds_conf:
1135 1193 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1136 1194 dds.save()
1137 1195
1138 ###### SIDEBAR ######
1139 1196 kwargs.update(sidebar(experiment=experiment))
1140
1141
1142
1143
1144
1145 1197 return render(request, 'experiment_verify.html', kwargs)
1146 1198
1147 1199
1148 #@user_passes_test(lambda u:u.is_staff)
1149 1200 def parse_mix_result(s):
1150 1201
1151 1202 values = s.split('-')
1152 1203 html = 'EXP MOD OPE DELAY MASK\r\n'
1153 1204
1154 1205 if not values or values[0] in ('', ' '):
1155 1206 return mark_safe(html)
1156 1207
1157 1208 for i, value in enumerate(values):
1158 1209 if not value:
1159 1210 continue
1160 1211 pk, mode, operation, delay, mask = value.split('|')
1161 1212 conf = RCConfiguration.objects.get(pk=pk)
1162 if i==0:
1213 if i == 0:
1163 1214 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1164 conf.name,
1165 mode,
1166 ' ',
1167 delay,
1168 mask)
1215 conf.name,
1216 mode,
1217 ' ',
1218 delay,
1219 mask)
1169 1220 else:
1170 1221 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1171 conf.name,
1172 mode,
1173 operation,
1174 delay,
1175 mask)
1222 conf.name,
1223 mode,
1224 operation,
1225 delay,
1226 mask)
1176 1227
1177 1228 return mark_safe(html)
1178 1229
1230
1179 1231 def parse_mask(l):
1180 1232
1181 1233 values = []
1182 1234
1183 for x in range(8):
1235 for x in range(16):
1184 1236 if '{}'.format(x) in l:
1185 1237 values.append(1)
1186 1238 else:
1187 1239 values.append(0)
1188 1240
1189 1241 values.reverse()
1190 1242
1191 1243 return int(''.join([str(x) for x in values]), 2)
1192 1244
1193 1245
1194 1246 def dev_confs(request):
1195 1247
1196
1197 1248 page = request.GET.get('page')
1198 order = ('type', 'device__device_type', 'experiment')
1249 order = ('programmed_date', )
1199 1250 filters = request.GET.copy()
1200
1251 if 'my configurations' in filters:
1252 filters.pop('my configurations', None)
1253 filters['mine'] = request.user.id
1201 1254 kwargs = get_paginator(Configuration, page, order, filters)
1202
1203 form = FilterForm(initial=request.GET, extra_fields=['tags', 'template', 'historical'])
1204 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1255 fields = ['tags', 'template', 'historical']
1256 if request.user.is_authenticated:
1257 fields.append('my configurations')
1258 form = FilterForm(initial=request.GET, extra_fields=fields)
1259 kwargs['keys'] = ['name', 'experiment',
1260 'type', 'programmed_date', 'actions']
1205 1261 kwargs['title'] = 'Configuration'
1206 1262 kwargs['suptitle'] = 'List'
1207 1263 kwargs['no_sidebar'] = True
1208 1264 kwargs['form'] = form
1265 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1266 filters = request.GET.copy()
1209 1267 filters.pop('page', None)
1210 1268 kwargs['q'] = urlencode(filters)
1211 1269
1212 1270 return render(request, 'base_list.html', kwargs)
1213 1271
1214 1272
1215 1273 def dev_conf(request, id_conf):
1216 1274
1217 1275 conf = get_object_or_404(Configuration, pk=id_conf)
1218 1276
1219 1277 return redirect(conf.get_absolute_url())
1220 1278
1221 1279
1222 @user_passes_test(lambda u:u.is_staff)
1280 @login_required
1223 1281 def dev_conf_new(request, id_exp=0, id_dev=0):
1224 1282
1283 if not is_developer(request.user):
1284 messages.error(
1285 request, 'Developer required, to create new configurations')
1286 return redirect('index')
1287
1225 1288 initial = {}
1226 1289 kwargs = {}
1227 1290
1228 if id_exp!=0:
1291 if id_exp != 0:
1229 1292 initial['experiment'] = id_exp
1230 1293
1231 if id_dev!=0:
1294 if id_dev != 0:
1232 1295 initial['device'] = id_dev
1233 1296
1234 1297 if request.method == 'GET':
1235 1298
1236 1299 if id_dev:
1237 1300 kwargs['button'] = 'Create'
1238 1301 device = Device.objects.get(pk=id_dev)
1239 1302 DevConfForm = CONF_FORMS[device.device_type.name]
1240 1303 initial['name'] = request.GET['name']
1241 1304 form = DevConfForm(initial=initial)
1242 1305 else:
1243 1306 if 'template' in request.GET:
1244 if request.GET['template']=='0':
1245 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1246 form = NewForm(initial={'create_from':2},
1307 if request.GET['template'] == '0':
1308 choices = [(conf.pk, '{}'.format(conf))
1309 for conf in Configuration.objects.filter(template=True)]
1310 form = NewForm(initial={'create_from': 2},
1247 1311 template_choices=choices)
1248 1312 else:
1249 1313 kwargs['button'] = 'Create'
1250 conf = Configuration.objects.get(pk=request.GET['template'])
1314 conf = Configuration.objects.get(
1315 pk=request.GET['template'])
1251 1316 id_dev = conf.device.pk
1252 1317 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1253 1318 form = DevConfForm(instance=conf,
1254 1319 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1255 1320 'template': False,
1256 'experiment':id_exp})
1321 'experiment': id_exp})
1257 1322 elif 'blank' in request.GET:
1258 1323 kwargs['button'] = 'Create'
1259 1324 form = ConfigurationForm(initial=initial)
1260 1325 else:
1261 1326 form = NewForm()
1262 1327
1263 1328 if request.method == 'POST':
1264 1329
1265 1330 device = Device.objects.get(pk=request.POST['device'])
1266 1331 DevConfForm = CONF_FORMS[device.device_type.name]
1267 1332
1268 1333 form = DevConfForm(request.POST)
1269 1334 kwargs['button'] = 'Create'
1270 1335 if form.is_valid():
1271 conf = form.save()
1336 conf = form.save(commit=False)
1337 conf.author = request.user
1338 conf.save()
1272 1339
1273 if 'template' in request.GET and conf.device.device_type.name=='rc':
1274 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1340 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1341 lines = RCLine.objects.filter(
1342 rc_configuration=request.GET['template'])
1275 1343 for line in lines:
1276 1344 line.clone(rc_configuration=conf)
1277 1345
1278 1346 new_lines = conf.get_lines()
1279 1347 for line in new_lines:
1280 1348 line_params = json.loads(line.params)
1281 1349 if 'TX_ref' in line_params:
1282 1350 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1283 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
1351 line_params['TX_ref'] = ['{}'.format(
1352 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1284 1353 line.params = json.dumps(line_params)
1285 1354 line.save()
1286 1355
1287 1356 return redirect('url_dev_conf', id_conf=conf.pk)
1288 1357
1289 1358 kwargs['id_exp'] = id_exp
1290 1359 kwargs['form'] = form
1291 1360 kwargs['title'] = 'Configuration'
1292 1361 kwargs['suptitle'] = 'New'
1293 1362
1294
1295 1363 if id_dev != 0:
1296 1364 device = Device.objects.get(pk=id_dev)
1297 1365 kwargs['device'] = device.device_type.name
1298 1366
1299 1367 return render(request, 'dev_conf_edit.html', kwargs)
1300 1368
1301 1369
1302 @user_passes_test(lambda u:u.is_staff)
1370 @login_required
1303 1371 def dev_conf_edit(request, id_conf):
1304 1372
1305 1373 conf = get_object_or_404(Configuration, pk=id_conf)
1306 1374
1307 1375 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1308 1376
1309 if request.method=='GET':
1377 if request.method == 'GET':
1310 1378 form = DevConfForm(instance=conf)
1311 1379
1312 if request.method=='POST':
1380 if request.method == 'POST':
1313 1381 form = DevConfForm(request.POST, instance=conf)
1314 1382
1315 1383 if form.is_valid():
1316 1384 form.save()
1317 1385 return redirect('url_dev_conf', id_conf=id_conf)
1318 1386
1319 1387 kwargs = {}
1320 1388 kwargs['form'] = form
1321 1389 kwargs['title'] = 'Device Configuration'
1322 1390 kwargs['suptitle'] = 'Edit'
1323 1391 kwargs['button'] = 'Update'
1324 1392
1325 1393 ###### SIDEBAR ######
1326 1394 kwargs.update(sidebar(conf=conf))
1327 1395
1328 1396 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1329 1397
1330 1398
1331 @user_passes_test(lambda u:u.is_staff)
1399 @login_required
1332 1400 def dev_conf_start(request, id_conf):
1333 1401
1334 1402 conf = get_object_or_404(Configuration, pk=id_conf)
1335 1403
1336 1404 if conf.start_device():
1337 1405 messages.success(request, conf.message)
1338 1406 else:
1339 1407 messages.error(request, conf.message)
1340 1408
1341 1409 #conf.status_device()
1342 1410
1343 1411 return redirect(conf.get_absolute_url())
1344 1412
1345 1413
1346 @user_passes_test(lambda u:u.is_staff)
1414 @login_required
1347 1415 def dev_conf_stop(request, id_conf):
1348 1416
1349 1417 conf = get_object_or_404(Configuration, pk=id_conf)
1350 1418
1351 1419 if conf.stop_device():
1352 1420 messages.success(request, conf.message)
1353 1421 else:
1354 1422 messages.error(request, conf.message)
1355 1423
1356 1424 #conf.status_device()
1357 1425
1358 1426 return redirect(conf.get_absolute_url())
1359 1427
1360 1428
1361 1429 def dev_conf_status(request, id_conf):
1362 1430
1363 1431 conf = get_object_or_404(Configuration, pk=id_conf)
1364 1432
1365 1433 if conf.status_device():
1366 1434 messages.success(request, conf.message)
1367 1435 else:
1368 1436 messages.error(request, conf.message)
1369 1437
1370 1438 return redirect(conf.get_absolute_url())
1371 1439
1372 1440
1373 @user_passes_test(lambda u:u.is_staff)
1441 @login_required
1374 1442 def dev_conf_reset(request, id_conf):
1375 1443
1376 1444 conf = get_object_or_404(Configuration, pk=id_conf)
1377 1445
1378 1446 if conf.reset_device():
1379 1447 messages.success(request, conf.message)
1380 1448 else:
1381 1449 messages.error(request, conf.message)
1382 1450
1383 1451 return redirect(conf.get_absolute_url())
1384 1452
1385 1453
1386 @user_passes_test(lambda u:u.is_staff)
1454 @login_required
1387 1455 def dev_conf_write(request, id_conf):
1388 1456
1389 1457 conf = get_object_or_404(Configuration, pk=id_conf)
1390 1458
1391 1459 if conf.write_device():
1392 1460 messages.success(request, conf.message)
1393 conf.clone(type=1, template=False)
1461 if has_been_modified(conf):
1462 conf.clone(type=1, template=False)
1394 1463 else:
1395 1464 messages.error(request, conf.message)
1396 1465
1397 1466 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1398 1467
1399 1468
1400 @user_passes_test(lambda u:u.is_staff)
1469 @login_required
1401 1470 def dev_conf_read(request, id_conf):
1402 1471
1403 1472 conf = get_object_or_404(Configuration, pk=id_conf)
1404 1473
1405 1474 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1406 1475
1407 if request.method=='GET':
1476 if request.method == 'GET':
1408 1477
1409 1478 parms = conf.read_device()
1410 1479 #conf.status_device()
1411 1480
1412 1481 if not parms:
1413 1482 messages.error(request, conf.message)
1414 1483 return redirect(conf.get_absolute_url())
1415 1484
1416 1485 form = DevConfForm(initial=parms, instance=conf)
1417 1486
1418 if request.method=='POST':
1487 if request.method == 'POST':
1419 1488 form = DevConfForm(request.POST, instance=conf)
1420 1489
1421 1490 if form.is_valid():
1422 1491 form.save()
1423 1492 return redirect(conf.get_absolute_url())
1424 1493
1425 1494 messages.error(request, "Parameters could not be saved")
1426 1495
1427 1496 kwargs = {}
1428 1497 kwargs['id_dev'] = conf.id
1429 1498 kwargs['form'] = form
1430 1499 kwargs['title'] = 'Device Configuration'
1431 1500 kwargs['suptitle'] = 'Parameters read from device'
1432 1501 kwargs['button'] = 'Save'
1433 1502
1434 1503 ###### SIDEBAR ######
1435 1504 kwargs.update(sidebar(conf=conf))
1436 1505
1437 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1506 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1438 1507
1439 1508
1440 @user_passes_test(lambda u:u.is_staff)
1509 @login_required
1441 1510 def dev_conf_import(request, id_conf):
1442 1511
1443 1512 conf = get_object_or_404(Configuration, pk=id_conf)
1444 1513 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1445 1514
1446 1515 if request.method == 'GET':
1447 1516 file_form = UploadFileForm()
1448 1517
1449 1518 if request.method == 'POST':
1450 1519 file_form = UploadFileForm(request.POST, request.FILES)
1451 1520
1452 1521 if file_form.is_valid():
1453 1522
1454 1523 data = conf.import_from_file(request.FILES['file'])
1455 parms = Params(data=data).get_conf(dtype=conf.device.device_type.name)
1524 parms = Params(data=data).get_conf(
1525 dtype=conf.device.device_type.name)
1456 1526
1457 1527 if parms:
1458 1528
1459 1529 form = DevConfForm(initial=parms, instance=conf)
1460 1530
1461 1531 kwargs = {}
1462 1532 kwargs['id_dev'] = conf.id
1463 1533 kwargs['form'] = form
1464 1534 kwargs['title'] = 'Device Configuration'
1465 1535 kwargs['suptitle'] = 'Parameters imported'
1466 1536 kwargs['button'] = 'Save'
1467 1537 kwargs['action'] = conf.get_absolute_url_edit()
1468 1538 kwargs['previous'] = conf.get_absolute_url()
1469 1539
1470 1540 ###### SIDEBAR ######
1471 1541 kwargs.update(sidebar(conf=conf))
1472 1542
1473 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1543 messages.success(
1544 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1474 1545
1475 1546 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1476 1547
1477 1548 messages.error(request, "Could not import parameters from file")
1478 1549
1479 1550 kwargs = {}
1480 1551 kwargs['id_dev'] = conf.id
1481 1552 kwargs['title'] = 'Device Configuration'
1482 1553 kwargs['form'] = file_form
1483 1554 kwargs['suptitle'] = 'Importing file'
1484 1555 kwargs['button'] = 'Import'
1485 1556
1486 1557 kwargs.update(sidebar(conf=conf))
1487 1558
1488 1559 return render(request, 'dev_conf_import.html', kwargs)
1489 1560
1490 1561
1491 @user_passes_test(lambda u:u.is_staff)
1562 @login_required
1492 1563 def dev_conf_export(request, id_conf):
1493 1564
1494 1565 conf = get_object_or_404(Configuration, pk=id_conf)
1495 1566
1496 1567 if request.method == 'GET':
1497 1568 file_form = DownloadFileForm(conf.device.device_type.name)
1498 1569
1499 1570 if request.method == 'POST':
1500 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1571 file_form = DownloadFileForm(
1572 conf.device.device_type.name, request.POST)
1501 1573
1502 1574 if file_form.is_valid():
1503 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1575 fields = conf.export_to_file(
1576 format=file_form.cleaned_data['format'])
1504 1577 if not fields['content']:
1505 1578 messages.error(request, conf.message)
1506 1579 return redirect(conf.get_absolute_url_export())
1507 1580 response = HttpResponse(content_type=fields['content_type'])
1508 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1581 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1509 1582 response.write(fields['content'])
1510 1583
1511 1584 return response
1512 1585
1513 1586 messages.error(request, "Could not export parameters")
1514 1587
1515 1588 kwargs = {}
1516 1589 kwargs['id_dev'] = conf.id
1517 1590 kwargs['title'] = 'Device Configuration'
1518 1591 kwargs['form'] = file_form
1519 1592 kwargs['suptitle'] = 'Exporting file'
1520 1593 kwargs['button'] = 'Export'
1521 1594
1522 1595 return render(request, 'dev_conf_export.html', kwargs)
1523 1596
1524 1597
1525 @user_passes_test(lambda u:u.is_staff)
1598 @login_required
1526 1599 def dev_conf_delete(request, id_conf):
1527 1600
1528 1601 conf = get_object_or_404(Configuration, pk=id_conf)
1529 1602
1530 if request.method=='POST':
1603 if request.method == 'POST':
1531 1604 if request.user.is_staff:
1532 1605 conf.delete()
1533 1606 return redirect('url_dev_confs')
1534 1607
1535 1608 messages.error(request, 'Not enough permission to delete this object')
1536 1609 return redirect(conf.get_absolute_url())
1537 1610
1538 1611 kwargs = {
1539 'title': 'Delete',
1540 'suptitle': 'Experiment',
1541 'object': conf,
1542 'previous': conf.get_absolute_url(),
1543 'delete': True
1544 }
1612 'title': 'Delete',
1613 'suptitle': 'Configuration',
1614 'object': conf,
1615 'delete': True
1616 }
1545 1617
1546 1618 return render(request, 'confirm.html', kwargs)
1547 1619
1548 1620
1549 1621 def sidebar(**kwargs):
1550 1622
1551 1623 side_data = {}
1552 1624
1553 1625 conf = kwargs.get('conf', None)
1554 1626 experiment = kwargs.get('experiment', None)
1555 1627
1556 1628 if not experiment:
1557 1629 experiment = conf.experiment
1558 1630
1559 1631 if experiment:
1560 1632 side_data['experiment'] = experiment
1561 1633 campaign = experiment.campaign_set.all()
1562 1634 if campaign:
1563 1635 side_data['campaign'] = campaign[0]
1564 experiments = campaign[0].experiments.all()
1636 experiments = campaign[0].experiments.all().order_by('name')
1565 1637 else:
1566 1638 experiments = [experiment]
1567 1639 configurations = experiment.configuration_set.filter(type=0)
1568 1640 side_data['side_experiments'] = experiments
1569 side_data['side_configurations'] = configurations
1641 side_data['side_configurations'] = configurations.order_by(
1642 'device__device_type__name')
1570 1643
1571 1644 return side_data
1572 1645
1573 def get_paginator(model, page, order, filters={}, n=10):
1646
1647 def get_paginator(model, page, order, filters={}, n=8):
1574 1648
1575 1649 kwargs = {}
1576 1650 query = Q()
1577 1651 if isinstance(filters, QueryDict):
1578 1652 filters = filters.dict()
1579 1653 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1580 1654 filters.pop('page', None)
1581 1655
1582 1656 fields = [f.name for f in model._meta.get_fields()]
1583 1657
1584 1658 if 'template' in filters:
1585 1659 filters['template'] = True
1586 1660 if 'historical' in filters:
1587 1661 filters.pop('historical')
1588 1662 filters['type'] = 1
1589 1663 elif 'type' in fields:
1590 1664 filters['type'] = 0
1591 1665 if 'start_date' in filters:
1592 1666 filters['start_date__gte'] = filters.pop('start_date')
1593 1667 if 'end_date' in filters:
1594 1668 filters['start_date__lte'] = filters.pop('end_date')
1595 1669 if 'tags' in filters:
1596 1670 tags = filters.pop('tags')
1597 1671 if 'tags' in fields:
1598 1672 query = query | Q(tags__icontains=tags)
1599 if 'name' in fields:
1600 query = query | Q(name__icontains=tags)
1673 if 'label' in fields:
1674 query = query | Q(label__icontains=tags)
1601 1675 if 'location' in fields:
1602 1676 query = query | Q(location__name__icontains=tags)
1603 1677 if 'device' in fields:
1604 1678 query = query | Q(device__device_type__name__icontains=tags)
1679 query = query | Q(device__location__name__icontains=tags)
1680 if 'device_type' in fields:
1681 query = query | Q(device_type__name__icontains=tags)
1605 1682
1683 if 'mine' in filters:
1684 filters['author_id'] = filters['mine']
1685 filters.pop('mine')
1606 1686 object_list = model.objects.filter(query, **filters).order_by(*order)
1607 1687 paginator = Paginator(object_list, n)
1608 1688
1609 1689 try:
1610 1690 objects = paginator.page(page)
1611 1691 except PageNotAnInteger:
1612 1692 objects = paginator.page(1)
1613 1693 except EmptyPage:
1614 1694 objects = paginator.page(paginator.num_pages)
1615 1695
1616 1696 kwargs['objects'] = objects
1617 1697 kwargs['offset'] = (int(page)-1)*n if page else 0
1618 1698
1619 1699 return kwargs
1620 1700
1701
1621 1702 def operation(request, id_camp=None):
1622 1703
1623 1704 kwargs = {}
1624 1705 kwargs['title'] = 'Radars Operation'
1625 1706 kwargs['no_sidebar'] = True
1626 1707 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1627 1708 end_date__gte=datetime.now()).order_by('-start_date')
1628 1709
1629
1630 1710 if id_camp:
1631 campaign = get_object_or_404(Campaign, pk = id_camp)
1632 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1711 campaign = get_object_or_404(Campaign, pk=id_camp)
1712 form = OperationForm(
1713 initial={'campaign': campaign.id}, campaigns=campaigns)
1633 1714 kwargs['campaign'] = campaign
1634 1715 else:
1635 1716 # form = OperationForm(campaigns=campaigns)
1636 1717 kwargs['campaigns'] = campaigns
1637 1718 return render(request, 'operation.html', kwargs)
1638 1719
1639 1720 #---Experiment
1640 1721 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1641 1722 kwargs['experiment_keys'] = keys[1:]
1642 1723 kwargs['experiments'] = experiments
1643 1724 #---Radar
1644 1725 kwargs['locations'] = campaign.get_experiments_by_radar()
1645 1726 kwargs['form'] = form
1646 1727
1647 1728 return render(request, 'operation.html', kwargs)
1648 1729
1649 1730
1650 1731 @login_required
1651 1732 def radar_start(request, id_camp, id_radar):
1652 1733
1653 campaign = get_object_or_404(Campaign, pk = id_camp)
1734 campaign = get_object_or_404(Campaign, pk=id_camp)
1654 1735 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1655 1736 now = datetime.now()
1656 1737 for exp in experiments:
1657 1738 start = datetime.combine(datetime.now().date(), exp.start_time)
1658 1739 end = datetime.combine(datetime.now().date(), exp.end_time)
1659 1740 if end < start:
1660 1741 end += timedelta(1)
1661
1742
1662 1743 if exp.status == 2:
1663 messages.warning(request, 'Experiment {} already running'.format(exp))
1744 messages.warning(
1745 request, 'Experiment {} already running'.format(exp))
1664 1746 continue
1665 1747
1666 1748 if exp.status == 3:
1667 messages.warning(request, 'Experiment {} already programmed'.format(exp))
1749 messages.warning(
1750 request, 'Experiment {} already programmed'.format(exp))
1668 1751 continue
1669 1752
1670 1753 if start > campaign.end_date or start < campaign.start_date:
1671 1754 messages.warning(request, 'Experiment {} out of date'.format(exp))
1672 1755 continue
1673 1756
1674 1757 if now > start and now <= end:
1675 1758 exp.status = 3
1676 1759 exp.save()
1677 1760 task = task_start.delay(exp.id)
1678 1761 exp.status = task.wait()
1679 if exp.status==0:
1762 if exp.status == 0:
1680 1763 messages.error(request, 'Experiment {} not start'.format(exp))
1681 if exp.status==2:
1764 if exp.status == 2:
1682 1765 messages.success(request, 'Experiment {} started'.format(exp))
1683 1766 else:
1684 task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))
1767 task = task_start.apply_async(
1768 (exp.pk, ), eta=start+timedelta(hours=5))
1685 1769 exp.task = task.id
1686 1770 exp.status = 3
1687 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1771 messages.success(
1772 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1688 1773
1689 1774 exp.save()
1690 1775
1691 1776 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1692 1777
1693 1778
1694 1779 @login_required
1695 1780 def radar_stop(request, id_camp, id_radar):
1696 1781
1697 campaign = get_object_or_404(Campaign, pk = id_camp)
1782 campaign = get_object_or_404(Campaign, pk=id_camp)
1698 1783 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1699 1784
1700 1785 for exp in experiments:
1701 1786
1702 1787 if exp.task:
1703 1788 app.control.revoke(exp.task)
1704 1789 if exp.status == 2:
1705 1790 exp.stop()
1706 1791 messages.warning(request, 'Experiment {} stopped'.format(exp))
1707 1792 exp.status = 1
1708 1793 exp.save()
1709 1794
1710 1795 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1711 1796
1712 1797
1713 1798 @login_required
1714 1799 def radar_refresh(request, id_camp, id_radar):
1715 1800
1716 campaign = get_object_or_404(Campaign, pk = id_camp)
1801 campaign = get_object_or_404(Campaign, pk=id_camp)
1717 1802 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1718 1803
1719 1804 for exp in experiments:
1720 1805 exp.get_status()
1721 1806
1722 1807 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1723 1808
1724 1809
1725 1810 def real_time(request):
1726 1811
1727 1812 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1728 1813
1729 1814 kwargs = {}
1730 1815 kwargs['title'] = 'CLAIRE'
1731 1816 kwargs['suptitle'] = 'Real Time'
1732 1817 kwargs['no_sidebar'] = True
1733 1818 kwargs['graphic_path'] = graphic_path
1734 1819 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1735 1820
1736 1821 return render(request, 'real_time.html', kwargs)
@@ -1,382 +1,384
1 1 import os
2 2 import json
3 3
4 4 from django import forms
5 5 from django.utils.safestring import mark_safe
6 6 from apps.main.models import Device
7 7 from apps.main.forms import add_empty_choice
8 8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
9 9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10 10
11 11 def create_choices_from_model(model, conf_id, all_choice=False):
12 12
13 13 if model=='RCLine':
14 14 instance = RCConfiguration.objects.get(pk=conf_id)
15 15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 16 if all_choice:
17 17 choices = add_empty_choice(choices, label='All')
18 18 else:
19 19 instance = globals()[model]
20 20 choices = instance.objects.all().values_list('pk', 'name')
21 21
22 22 return choices
23 23
24 24
25 25 class ExtFileField(forms.FileField):
26 26 """
27 27 Same as forms.FileField, but you can specify a file extension whitelist.
28 28
29 29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 30 >>>
31 31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 32 >>>
33 33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 35 >>>
36 36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 37 Traceback (most recent call last):
38 38 ...
39 39 ValidationError: [u'Not allowed filetype!']
40 40 """
41 41 def __init__(self, *args, **kwargs):
42 42 extensions = kwargs.pop("extensions")
43 43 self.extensions = [i.lower() for i in extensions]
44 44
45 45 super(ExtFileField, self).__init__(*args, **kwargs)
46 46
47 47 def clean(self, *args, **kwargs):
48 48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 49 filename = data.name
50 50 ext = os.path.splitext(filename)[1]
51 51 ext = ext.lower()
52 52 if ext not in self.extensions:
53 53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54 54
55 55
56 56 class RCConfigurationForm(forms.ModelForm):
57 57
58 58 def __init__(self, *args, **kwargs):
59 59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60 60
61 61 instance = getattr(self, 'instance', None)
62 62
63 63 if instance and instance.pk:
64 64
65 65 devices = Device.objects.filter(device_type__name='rc')
66 66 if instance.experiment:
67 67 self.fields['experiment'].widget.attrs['read_only'] = True
68 68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 71 self.fields['clock'].widget.attrs['readonly'] = True
72 72
73 73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75 75
76 76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 77 self.fields['experiment'].widget.attrs['readonly'] = True
78 78
79 79 class Meta:
80 80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash')
82 82
83 83 def clean(self):
84 84 form_data = super(RCConfigurationForm, self).clean()
85 85
86 86 if 'clock_divider' in form_data:
87 87 if form_data['clock_divider']<1:
88 88 self.add_error('clock_divider', 'Invalid Value')
89 89 #else:
90 90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
91 91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92 92
93 93 return form_data
94 94
95 def save(self):
96 conf = super(RCConfigurationForm, self).save()
95 def save(self, *args, **kwargs):
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
97 97 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
98 98 conf.save()
99 99 return conf
100 100
101 101
102 102 class RCMixConfigurationForm(forms.Form):
103 103
104 104 clock_in = forms.CharField(widget=forms.HiddenInput())
105 105 clock_divider = forms.CharField(widget=forms.HiddenInput())
106 106 name = forms.CharField()
107 107 experiment = forms.ChoiceField()
108 108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
109 109 choices=[(0, 'Parallel'), (1, 'Sequence')],
110 110 initial=0)
111 111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
112 112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
113 113 initial=1)
114 114 delay = forms.CharField()
115 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
116 widget=HCheckboxSelectMultiple())
115 mask = forms.MultipleChoiceField(
116 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
117 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
118 widget=HCheckboxSelectMultiple())
117 119 result = forms.CharField(required=False,
118 120 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
119 121
120 122 def __init__(self, *args, **kwargs):
121 123 confs = kwargs.pop('confs', [])
122 124 if confs:
123 125 km2unit = confs[0].km2unit
124 126 clock_in = confs[0].clock_in
125 127 clock_divider = confs[0].clock_divider
126 128 else:
127 129 km2unit = clock_in = clock_divider = 0
128 130 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
129 131 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
130 132 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
131 133 self.fields['clock_in'].initial = clock_in
132 134 self.fields['clock_divider'].initial = clock_divider
133 135
134 136
135 137 class RCLineForm(forms.ModelForm):
136 138
137 139 def __init__(self, *args, **kwargs):
138 140 self.extra_fields = kwargs.pop('extra_fields', [])
139 141 super(RCLineForm, self).__init__(*args, **kwargs)
140 142
141 143 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
142 144 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
143 145
144 146 if 'code_id' in kwargs['initial']:
145 147 model_initial = kwargs['initial']['code_id']
146 148 else:
147 149 model_initial = 0
148 150
149 151 params = json.loads(line_type.params)
150 152
151 153 for label, value in self.extra_fields.items():
152 154 if label=='params':
153 155 continue
154 156
155 157 if 'model' in params[label]:
156 158 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
157 159 kwargs['initial']['rc_configuration']),
158 160 initial=model_initial)
159 161
160 162
161 163 else:
162 164 if label=='codes' and 'code_id' in kwargs['initial']:
163 165 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
164 166 else:
165 167 self.fields[label] = forms.CharField(initial=value['value'])
166 168
167 169 if label=='codes':
168 170 self.fields[label].widget = CodesWidget()
169 171
170 172 if self.data:
171 173 line_type = RCLineType.objects.get(pk=self.data['line_type'])
172 174
173 175 if 'code_id' in self.data:
174 176 model_initial = self.data['code_id']
175 177 else:
176 178 model_initial = 0
177 179
178 180 params = json.loads(line_type.params)
179 181
180 182 for label, value in self.extra_fields.items():
181 183 if label=='params':
182 184 continue
183 185
184 186 if 'model' in params[label]:
185 187 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
186 188 self.data['rc_configuration']),
187 189 initial=model_initial)
188 190
189 191
190 192 else:
191 193 if label=='codes' and 'code' in self.data:
192 194 self.fields[label] = forms.CharField(initial=self.data['codes'])
193 195 else:
194 196 self.fields[label] = forms.CharField(initial=self.data[label])
195 197
196 198 if label=='codes':
197 199 self.fields[label].widget = CodesWidget()
198 200
199 201
200 202 class Meta:
201 203 model = RCLine
202 204 fields = ('rc_configuration', 'line_type', 'channel')
203 205 widgets = {
204 206 'channel': forms.HiddenInput(),
205 207 }
206 208
207 209
208 210 def clean(self):
209 211
210 212 form_data = self.cleaned_data
211 213 if 'code' in self.data and self.data['TX_ref']=="0":
212 214 self.add_error('TX_ref', 'Choose a valid TX reference')
213 215
214 216 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
215 217 self.add_error('line_type', 'Invalid Line type')
216 218
217 219 return form_data
218 220
219 221
220 222 def save(self):
221 223 line = super(RCLineForm, self).save()
222 224
223 225 #auto add channel
224 226 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
225 227
226 228 #auto add position for TX, TR & CODE
227 229 if line.line_type.name in ('tx', ):
228 230 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
229 231
230 232 #save extra fields in params
231 233 params = {}
232 234 for label, value in self.extra_fields.items():
233 235 if label=='params':
234 236 params['params'] = []
235 237 elif label=='codes':
236 238 params[label] = [s for s in self.data[label].split('\r\n') if s]
237 239 else:
238 240 params[label] = self.data[label]
239 241 line.params = json.dumps(params)
240 242 line.save()
241 243 return
242 244
243 245
244 246 class RCLineViewForm(forms.Form):
245 247
246 248 def __init__(self, *args, **kwargs):
247 249
248 250 extra_fields = kwargs.pop('extra_fields')
249 251 line = kwargs.pop('line')
250 252 subform = kwargs.pop('subform', False)
251 253 super(RCLineViewForm, self).__init__(*args, **kwargs)
252 254
253 255 if subform:
254 256 params = json.loads(line.line_type.params)['params']
255 257 else:
256 258 params = json.loads(line.line_type.params)
257 259
258 260 for label, value in extra_fields.items():
259 261
260 262 if label=='params':
261 263 continue
262 264 if 'ref' in label:
263 265 if value in (0, '0'):
264 266 value = 'All'
265 267 else:
266 268 value = RCLine.objects.get(pk=value).get_name()
267 269 elif label=='code':
268 270 value = RCLineCode.objects.get(pk=value).name
269 271
270 272 self.fields[label] = forms.CharField(initial=value)
271 273
272 274 if 'widget' in params[label]:
273 275 km2unit = line.rc_configuration.km2unit
274 276 if params[label]['widget']=='km':
275 277 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
276 278 elif params[label]['widget']=='unit':
277 279 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
278 280 elif params[label]['widget']=='dc':
279 281 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 282 elif params[label]['widget']=='codes':
281 283 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 284 else:
283 285 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
284 286
285 287
286 288 class RCLineEditForm(forms.ModelForm):
287 289
288 290 def __init__(self, *args, **kwargs):
289 291
290 292 extra_fields = kwargs.pop('extra_fields', [])
291 293 conf = kwargs.pop('conf', False)
292 294 line = kwargs.pop('line')
293 295 subform = kwargs.pop('subform', False)
294 296
295 297 super(RCLineEditForm, self).__init__(*args, **kwargs)
296 298
297 299 if subform is not False:
298 300 params = json.loads(line.line_type.params)['params']
299 301 count = subform
300 302 else:
301 303 params = json.loads(line.line_type.params)
302 304 count = -1
303 305
304 306 for label, value in extra_fields.items():
305 307
306 308 if label in ('params',):
307 309 continue
308 310 if 'help' in params[label]:
309 311 help_text = params[label]['help']
310 312 else:
311 313 help_text = ''
312 314
313 315 if 'model' in params[label]:
314 316 if line.line_type.name=='tr':
315 317 all_choice = True
316 318 else:
317 319 all_choice = False
318 320 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
319 321 initial=value,
320 322 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
321 323 help_text=help_text)
322 324
323 325 else:
324 326 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
325 327
326 328 if label in ('code', ):
327 329 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
328 330
329 331 elif 'widget' in params[label]:
330 332 km2unit = line.rc_configuration.km2unit
331 333 if params[label]['widget']=='km':
332 334 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
333 335 elif params[label]['widget']=='unit':
334 336 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
335 337 elif params[label]['widget']=='dc':
336 338 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
337 339 elif params[label]['widget']=='codes':
338 340 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 341 else:
340 342 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
341 343
342 344
343 345 class Meta:
344 346 model = RCLine
345 347 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
346 348
347 349
348 350 class RCSubLineEditForm(forms.Form):
349 351
350 352 def __init__(self, *args, **kwargs):
351 353 extra_fields = kwargs.pop('extra_fields')
352 354 count = kwargs.pop('count')
353 355 line = kwargs.pop('line')
354 356 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
355 357 for label, value in extra_fields.items():
356 358 self.fields[label] = forms.CharField(initial=value,
357 359 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
358 360
359 361
360 362 class RCImportForm(forms.Form):
361 363
362 364 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
363 365
364 366
365 367 class RCLineCodesForm(forms.ModelForm):
366 368
367 369 def __init__(self, *args, **kwargs):
368 370 super(RCLineCodesForm, self).__init__(*args, **kwargs)
369 371
370 372 if 'initial' in kwargs:
371 373 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
372 374 initial=kwargs['initial']['code'])
373 375 if 'instance' in kwargs:
374 376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
375 377 initial=kwargs['instance'].pk)
376 378
377 379 self.fields['codes'].widget = CodesWidget()
378 380
379 381
380 382 class Meta:
381 383 model = RCLineCode
382 384 exclude = ('name',)
@@ -1,1001 +1,1004
1 1
2 2
3 3 import ast
4 4 import json
5 5 import requests
6 6 import numpy as np
7 7 from base64 import b64encode
8 8 from struct import pack
9 9
10 10 from django.db import models
11 11 from django.core.urlresolvers import reverse
12 12 from django.core.validators import MinValueValidator, MaxValueValidator
13 13
14 14 from apps.main.models import Configuration
15 15 from apps.main.utils import Params
16 16 from devices.rc import api
17 17 from apps.rc.utils import RCFile
18 18
19 19
20 20 LINE_TYPES = (
21 21 ('none', 'Not used'),
22 22 ('tr', 'Transmission/reception selector signal'),
23 23 ('tx', 'A modulating signal (Transmission pulse)'),
24 24 ('codes', 'BPSK modulating signal'),
25 25 ('windows', 'Sample window signal'),
26 26 ('sync', 'Synchronizing signal'),
27 27 ('flip', 'IPP related periodic signal'),
28 28 ('prog_pulses', 'Programmable pulse'),
29 29 ('mix', 'Mixed line'),
30 30 )
31 31
32 32
33 33 SAMPLING_REFS = (
34 34 ('none', 'No Reference'),
35 35 ('begin_baud', 'Begin of the first baud'),
36 36 ('first_baud', 'Middle of the first baud'),
37 37 ('sub_baud', 'Middle of the sub-baud')
38 38 )
39 39
40 40 DAT_CMDS = {
41 41 # Pulse Design commands
42 42 'DISABLE' : 0, # Disables pulse generation
43 43 'ENABLE' : 24, # Enables pulse generation
44 44 'DELAY_START' : 40, # Write delay status to memory
45 45 'FLIP_START' : 48, # Write flip status to memory
46 46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
47 47 'TX_ONE' : 72, # Output '0' in line TX
48 48 'TX_ZERO' : 88, # Output '0' in line TX
49 49 'SW_ONE' : 104, # Output '0' in line SW
50 50 'SW_ZERO' : 112, # Output '1' in line SW
51 51 'RESTART': 120, # Restarts CR8 Firmware
52 52 'CONTINUE' : 253, # Function Unknown
53 53 # Commands available to new controllers
54 54 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
55 55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
56 56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
57 57 'CLOCK_DIVIDER' : 8,
58 58 }
59 59
60 60 MAX_BITS = 8
61 61
62 62 # Rotate left: 0b1001 --> 0b0011
63 63 rol = lambda val, r_bits: \
64 64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
65 65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
66 66
67 67 # Rotate right: 0b1001 --> 0b1100
68 68 ror = lambda val, r_bits: \
69 69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
70 70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
71 71
72 72
73 73 class RCConfiguration(Configuration):
74 74
75 75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
80 80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
81 81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
82 82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
83 83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 86 total_units = models.PositiveIntegerField(default=0)
87 87 mix = models.BooleanField(default=False)
88 88
89 89 class Meta:
90 90 db_table = 'rc_configurations'
91 91
92 92 def get_absolute_url_plot(self):
93 93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94 94
95 95 @property
96 96 def ipp_unit(self):
97 97
98 98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99 99
100 100 @property
101 101 def us2unit(self):
102 102
103 103 return self.clock_in/self.clock_divider
104 104
105 105 @property
106 106 def km2unit(self):
107 107
108 108 return 20./3*(self.clock_in/self.clock_divider)
109 109
110 110 def clone(self, **kwargs):
111 111
112 112 lines = self.get_lines()
113 113 self.pk = None
114 114 self.id = None
115 115 for attr, value in kwargs.items():
116 116 setattr(self, attr, value)
117 117 self.save()
118 118
119 119 for line in lines:
120 120 line.clone(rc_configuration=self)
121 121
122 122 new_lines = self.get_lines()
123 123 for line in new_lines:
124 124 line_params = json.loads(line.params)
125 125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 128 line.params = json.dumps(line_params)
129 129 line.save()
130 130
131 131 return self
132 132
133 133 def get_lines(self, **kwargs):
134 134 '''
135 135 Retrieve configuration lines
136 136 '''
137 137
138 138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139 139
140 140
141 141 def clean_lines(self):
142 142 '''
143 143 '''
144 144
145 145 empty_line = RCLineType.objects.get(name='none')
146 146
147 147 for line in self.get_lines():
148 148 line.line_type = empty_line
149 149 line.params = '{}'
150 150 line.save()
151 151
152 152 def dict_to_parms(self, params, id=None):
153 153 '''
154 154 '''
155 155
156 156 if id:
157 157 data = Params(params).get_conf(id_conf=id)
158 158 else:
159 159 data = Params(params).get_conf(dtype='rc')
160 160
161 self.name = data['name']
161 # self.name = data['name']
162 162 self.ipp = data['ipp']
163 163 self.ntx = data['ntx']
164 164 self.clock_in = data['clock_in']
165 165 self.clock_divider = data['clock_divider']
166 166 self.clock = data['clock']
167 167 self.time_before = data['time_before']
168 168 self.time_after = data['time_after']
169 169 self.sync = data['sync']
170 170 self.sampling_reference = data['sampling_reference']
171 171 self.total_units = self.ipp*self.ntx*self.km2unit
172 172 self.save()
173 173 self.clean_lines()
174 174
175 175 positions = {'tx':0, 'tr':0}
176 176 for i, id in enumerate(data['lines']):
177 177 line_data = params['lines']['byId'][id]
178 178 line_type = RCLineType.objects.get(name=line_data['line_type'])
179 179 if line_type.name == 'codes':
180 180 code = RCLineCode.objects.get(name=line_data['params']['code'])
181 181 line_data['params']['code'] = code.pk
182 182 if line_type.name == 'tx':
183 183 position = positions['tx']
184 184 positions['tx'] += 1
185 185 elif line_type.name == 'tr':
186 186 position = positions['tr']
187 187 positions['tr'] += 1
188 188 else:
189 189 position = 0
190 190 line, dum = RCLine.objects.update_or_create(
191 191 rc_configuration=self,
192 192 channel=i,
193 193 position=position,
194 194 defaults={
195 195 'line_type': line_type,
196 196 'params': json.dumps(line_data['params'])
197 197 }
198 198 )
199 199
200 200 for i, line in enumerate(self.get_lines()):
201 201 line_params = json.loads(line.params)
202 202 if 'TX_ref' in line_params:
203 203 if line_params['TX_ref'] in (0, '0'):
204 204 line_params['TX_ref'] = '0'
205 205 else:
206 206 ref_id = '{}'.format(line_params['TX_ref'])
207 207 ref_line = params['lines']['byId'][ref_id]
208 208 line_params['TX_ref'] = RCLine.objects.get(
209 209 rc_configuration=self,
210 210 params=json.dumps(ref_line['params'])
211 211 ).pk
212 212 line.params = json.dumps(line_params)
213 213 line.save()
214 214
215 215
216 216 def get_delays(self):
217 217
218 218 pulses = [line.pulses_as_points() for line in self.get_lines()]
219 219 points = [tup for tups in pulses for tup in tups]
220 220 points = set([x for tup in points for x in tup])
221 221 points = list(points)
222 222 points.sort()
223 223
224 224 if points[0]!=0:
225 225 points.insert(0, 0)
226 226
227 227 return [points[i+1]-points[i] for i in range(len(points)-1)]
228 228
229 229
230 230 def get_pulses(self, binary=True):
231 231
232 232 pulses = [line.pulses_as_points() for line in self.get_lines()]
233 233 tuples = [tup for tups in pulses for tup in tups]
234 234 points = set([x for tup in tuples for x in tup])
235 235 points = list(points)
236 236 points.sort()
237 237 states = []
238 238 last = [0 for x in pulses]
239 239
240 240 for x in points:
241 241 dum = []
242 242 for i, tups in enumerate(pulses):
243 243 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 244 dws = [tup[1] for tup in tups if tup!=(0,0)]
245 245 if x in ups:
246 246 dum.append(1)
247 247 elif x in dws:
248 248 dum.append(0)
249 249 else:
250 250 dum.append(last[i])
251 251 states.append(dum)
252 252 last = dum
253 253
254 254 if binary:
255 255 ret = []
256 256 for flips in states:
257 257 flips.reverse()
258 258 ret.append(int(''.join([str(x) for x in flips]), 2))
259 259 states = ret
260 260
261 261 return states[:-1]
262 262
263 263 def add_cmd(self, cmd):
264 264
265 265 if cmd in DAT_CMDS:
266 266 return (255, DAT_CMDS[cmd])
267 267
268 268 def add_data(self, value):
269 269
270 270 return (254, value-1)
271 271
272 272 def parms_to_binary(self, dat=True):
273 273 '''
274 274 Create "dat" stream to be send to CR
275 275 '''
276 276
277 277 data = bytearray()
278 278 # create header
279 279 data.extend(self.add_cmd('DISABLE'))
280 280 data.extend(self.add_cmd('CONTINUE'))
281 281 data.extend(self.add_cmd('RESTART'))
282 282
283 283 if self.control_sw:
284 284 data.extend(self.add_cmd('SW_ONE'))
285 285 else:
286 286 data.extend(self.add_cmd('SW_ZERO'))
287 287
288 288 if self.control_tx:
289 289 data.extend(self.add_cmd('TX_ONE'))
290 290 else:
291 291 data.extend(self.add_cmd('TX_ZERO'))
292 292
293 293 # write divider
294 294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
295 295 data.extend(self.add_data(self.clock_divider))
296 296
297 297 # write delays
298 298 data.extend(self.add_cmd('DELAY_START'))
299 299 # first delay is always zero
300 300 data.extend(self.add_data(1))
301 301
302 302 delays = self.get_delays()
303 303
304 304 for delay in delays:
305 305 while delay>252:
306 306 data.extend(self.add_data(253))
307 307 delay -= 253
308 308 data.extend(self.add_data(int(delay)))
309 309
310 310 # write flips
311 311 data.extend(self.add_cmd('FLIP_START'))
312 312
313 313 states = self.get_pulses(binary=True)
314 314
315 315
316 316 last = 0
317 317 for flip, delay in zip(states, delays):
318 318 data.extend(self.add_data((flip^last)+1))
319 319 last = flip
320 320 while delay>252:
321 321 data.extend(self.add_data(1))
322 322 delay -= 253
323 323
324 324 # write sampling period
325 325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
326 326 wins = self.get_lines(line_type__name='windows')
327 327 if wins:
328 328 win_params = json.loads(wins[0].params)['params']
329 329 if win_params:
330 330 dh = int(win_params[0]['resolution']*self.km2unit)
331 331 else:
332 332 dh = 1
333 333 else:
334 334 dh = 1
335 335 data.extend(self.add_data(dh))
336 336
337 337 # write enable
338 338 data.extend(self.add_cmd('ENABLE'))
339 339
340 340 if not dat:
341 341 return data
342 342
343 343 return '\n'.join(['{}'.format(x) for x in data])
344 344
345 345 def update_pulses(self):
346 346
347 347 for line in self.get_lines():
348 348 line.update_pulses()
349 349
350 350 def plot_pulses2(self, km=False):
351 351
352 352 import matplotlib
353 353 matplotlib.use('Agg')
354 354 import matplotlib.pyplot as plt
355 355 from bokeh.resources import CDN
356 356 from bokeh.embed import components
357 357 from bokeh.mpl import to_bokeh
358 358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
359 359
360 360 lines = self.get_lines()
361 361
362 362 N = len(lines)
363 363 npoints = self.total_units/self.km2unit if km else self.total_units
364 364 fig = plt.figure(figsize=(12, 2+N*0.5))
365 365 ax = fig.add_subplot(111)
366 366 labels = ['IPP']
367 367
368 368 for i, line in enumerate(lines):
369 369 labels.append(line.get_name(channel=True))
370 370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
371 371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
372 372 ax.broken_barh(points, (N-i-1, 0.5),
373 373 edgecolor=l[0].get_color(), facecolor='none')
374 374
375 375 n = 0
376 376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
377 377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
378 378 if n%f==0:
379 379 ax.text(x, N, '%s' % n, size=10)
380 380 n += 1
381 381
382 382 labels.reverse()
383 383 ax.set_yticks(range(len(labels)))
384 384 ax.set_yticklabels(labels)
385 385 ax.set_xlabel = 'Units'
386 386 plot = to_bokeh(fig, use_pandas=False)
387 387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
388 388 plot.toolbar_location="above"
389 389
390 390 return components(plot, CDN)
391 391
392 392 def plot_pulses(self, km=False):
393 393
394 394 from bokeh.plotting import figure
395 395 from bokeh.resources import CDN
396 396 from bokeh.embed import components
397 397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 399 from bokeh.models.sources import ColumnDataSource
400 400
401 401 lines = self.get_lines().reverse()
402 402
403 403 N = len(lines)
404 404 npoints = self.total_units/self.km2unit if km else self.total_units
405 405 ipp = self.ipp if km else self.ipp*self.km2unit
406 406
407 407 hover = HoverTool(tooltips=[("Line", "@name"),
408 408 ("IPP", "@ipp"),
409 409 ("X", "@left")])
410 410
411 411 tools = [PanTool(dimensions=['width']),
412 412 WheelZoomTool(dimensions=['width']),
413 413 hover, SaveTool()]
414 414
415 415 plot = figure(width=1000,
416 416 height=40+N*50,
417 417 y_range = (0, N),
418 418 tools=tools,
419 419 toolbar_location='above',
420 420 toolbar_sticky=False,)
421 421
422 422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 424 plot.yaxis.axis_label = 'Pulses'
425 425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427 427
428 428 for i, line in enumerate(lines):
429 429
430 430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431 431
432 432 source = ColumnDataSource(data = dict(
433 433 bottom = [i for tup in points],
434 434 top = [i+0.5 for tup in points],
435 435 left = [tup[0] for tup in points],
436 436 right = [tup[1] for tup in points],
437 437 ipp = [int(tup[0]/ipp) for tup in points],
438 438 name = [line.get_name() for tup in points]
439 439 ))
440 440
441 441 plot.quad(
442 442 bottom = 'bottom',
443 443 top = 'top',
444 444 left = 'left',
445 445 right = 'right',
446 446 source = source,
447 447 fill_alpha = 0,
448 448 #line_color = 'blue',
449 449 )
450 450
451 451 plot.line([0, npoints], [i, i])#, color='blue')
452 452
453 453 return components(plot, CDN)
454 454
455 455 def request(self, cmd, method='get', **kwargs):
456 456
457 457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
458 458 payload = req.json()
459 459
460 460 return payload
461 461
462 462 def status_device(self):
463 463
464 464 try:
465 465 self.device.status = 0
466 466 payload = self.request('status')
467 467 if payload['status']=='enable':
468 468 self.device.status = 3
469 469 elif payload['status']=='disable':
470 470 self.device.status = 2
471 471 else:
472 472 self.device.status = 1
473 473 self.device.save()
474 474 self.message = 'RC status: {}'.format(payload['status'])
475 475 return False
476 476 except Exception as e:
477 477 if 'No route to host' not in str(e):
478 478 self.device.status = 4
479 479 self.device.save()
480 480 self.message = 'RC status: {}'.format(str(e))
481 481 return False
482 482
483 483 self.device.save()
484 484 return True
485 485
486 486 def reset_device(self):
487 487
488 488 try:
489 489 payload = self.request('reset', 'post')
490 490 if payload['reset']=='ok':
491 491 self.message = 'RC restarted OK'
492 492 self.device.status = 2
493 493 self.device.save()
494 494 else:
495 495 self.message = 'RC restart fail'
496 496 self.device.status = 4
497 497 self.device.save()
498 498 except Exception as e:
499 499 self.message = 'RC reset: {}'.format(str(e))
500 500 return False
501 501
502 502 return True
503 503
504 504 def stop_device(self):
505 505
506 506 try:
507 507 payload = self.request('stop', 'post')
508 508 self.message = 'RC stop: {}'.format(payload['stop'])
509 509 if payload['stop']=='ok':
510 510 self.device.status = 2
511 511 self.device.save()
512 512 else:
513 513 self.device.status = 4
514 514 self.device.save()
515 515 return False
516 516 except Exception as e:
517 517 if 'No route to host' not in str(e):
518 518 self.device.status = 4
519 519 else:
520 520 self.device.status = 0
521 521 self.message = 'RC stop: {}'.format(str(e))
522 522 self.device.save()
523 523 return False
524 524
525 525 return True
526 526
527 527 def start_device(self):
528 528
529 529 try:
530 530 payload = self.request('start', 'post')
531 531 self.message = 'RC start: {}'.format(payload['start'])
532 532 if payload['start']=='ok':
533 533 self.device.status = 3
534 534 self.device.save()
535 535 else:
536 536 return False
537 537 except Exception as e:
538 538 if 'No route to host' not in str(e):
539 539 self.device.status = 4
540 540 else:
541 541 self.device.status = 0
542 542 self.message = 'RC start: {}'.format(str(e))
543 543 self.device.save()
544 544 return False
545 545
546 546 return True
547 547
548 def write_device(self):
548 def write_device(self, raw=False):
549 549
550 550 values = []
551 551 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
552 552 while delay>65536:
553 553 values.append((pulse, 65535))
554 554 delay -= 65536
555 555 values.append((pulse, delay-1))
556 556 data = bytearray()
557 557 #reset
558 558 data.extend((128, 0))
559 559 #disable
560 560 data.extend((129, 0))
561 561 #SW switch
562 562 if self.control_sw:
563 563 data.extend((130, 2))
564 564 else:
565 565 data.extend((130, 0))
566 566 #divider
567 567 data.extend((131, self.clock_divider-1))
568 568 #enable writing
569 569 data.extend((139, 62))
570 570
571 571 last = 0
572 572 for tup in values:
573 573 vals = pack('<HH', last^tup[0], tup[1])
574 574 last = tup[0]
575 575 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
576 576
577 577 #enable
578 578 data.extend((129, 1))
579 579
580 if raw:
581 return b64encode(data)
582
580 583 try:
581 584 payload = self.request('stop', 'post')
582 585 payload = self.request('reset', 'post')
583 586 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
584 587 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
585 588 n = len(data)
586 589 x = 0
587 590 #while x < n:
588 591 payload = self.request('write', 'post', data=b64encode(data))
589 592 # x += 1024
590 593
591 594 if payload['write']=='ok':
592 595 self.device.status = 3
593 596 self.device.save()
594 597 self.message = 'RC configured and started'
595 598 else:
596 599 self.device.status = 1
597 600 self.device.save()
598 601 self.message = 'RC write: {}'.format(payload['write'])
599 602 return False
600 603
601 604 #payload = self.request('start', 'post')
602 605
603 606 except Exception as e:
604 607 if 'No route to host' not in str(e):
605 608 self.device.status = 4
606 609 else:
607 610 self.device.status = 0
608 611 self.message = 'RC write: {}'.format(str(e))
609 612 self.device.save()
610 613 return False
611 614
612 615 return True
613 616
614 617
615 618 def get_absolute_url_import(self):
616 619 return reverse('url_import_rc_conf', args=[str(self.id)])
617 620
618 621
619 622 class RCLineCode(models.Model):
620 623
621 624 name = models.CharField(max_length=40)
622 625 bits_per_code = models.PositiveIntegerField(default=0)
623 626 number_of_codes = models.PositiveIntegerField(default=0)
624 627 codes = models.TextField(blank=True, null=True)
625 628
626 629 class Meta:
627 630 db_table = 'rc_line_codes'
628 631 ordering = ('name',)
629 632
630 633 def __str__(self):
631 634 return u'%s' % self.name
632 635
633 636
634 637 class RCLineType(models.Model):
635 638
636 639 name = models.CharField(choices=LINE_TYPES, max_length=40)
637 640 description = models.TextField(blank=True, null=True)
638 641 params = models.TextField(default='[]')
639 642
640 643 class Meta:
641 644 db_table = 'rc_line_types'
642 645
643 646 def __str__(self):
644 647 return u'%s - %s' % (self.name.upper(), self.get_name_display())
645 648
646 649
647 650 class RCLine(models.Model):
648 651
649 652 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
650 653 line_type = models.ForeignKey(RCLineType)
651 654 channel = models.PositiveIntegerField(default=0)
652 655 position = models.PositiveIntegerField(default=0)
653 656 params = models.TextField(default='{}')
654 657 pulses = models.TextField(default='')
655 658
656 659 class Meta:
657 660 db_table = 'rc_lines'
658 661 ordering = ['channel']
659 662
660 663 def __str__(self):
661 664 if self.rc_configuration:
662 665 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
663 666
664 667 def jsonify(self):
665 668
666 669 data = {}
667 670 data['params'] = json.loads(self.params)
668 671 data['id'] = '{}'.format(self.pk)
669 672 data['line_type'] = self.line_type.name
670 673 data['name'] = self.get_name()
671 674 if data['line_type']=='codes':
672 675 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
673 676
674 677 return data
675 678
676 679
677 680 def clone(self, **kwargs):
678 681
679 682 self.pk = None
680 683 self.id = None
681 684
682 685 for attr, value in kwargs.items():
683 686 setattr(self, attr, value)
684 687
685 688 self.save()
686 689
687 690 return self
688 691
689 692 def get_name(self, channel=False):
690 693
691 694 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
692 695 s = ''
693 696
694 697 if self.line_type.name in ('tx',):
695 698 s = chars[self.position]
696 699 elif self.line_type.name in ('codes', 'windows', 'tr'):
697 700 if 'TX_ref' in json.loads(self.params):
698 701 pk = json.loads(self.params)['TX_ref']
699 702 if pk in (0, '0'):
700 703 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
701 704 else:
702 705 ref = RCLine.objects.get(pk=pk)
703 706 s = chars[ref.position]
704 707 s = '({})'.format(s)
705 708
706 709 s = '{}{}'.format(self.line_type.name.upper(), s)
707 710
708 711 if channel:
709 712 return '{} {}'.format(s, self.channel)
710 713 else:
711 714 return s
712 715
713 716 def get_lines(self, **kwargs):
714 717
715 718 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
716 719
717 720 def pulses_as_array(self):
718 721
719 722 y = np.zeros(self.rc_configuration.total_units)
720 723
721 724 for tup in ast.literal_eval(self.pulses):
722 725 y[tup[0]:tup[1]] = 1
723 726
724 727 return y.astype(np.int8)
725 728
726 729 def pulses_as_points(self, km=False):
727 730
728 731 if km:
729 732 unit2km = 1/self.rc_configuration.km2unit
730 733 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
731 734 else:
732 735 return ast.literal_eval(self.pulses)
733 736
734 737 def get_win_ref(self, params, tx_id, km2unit):
735 738
736 739 ref = self.rc_configuration.sampling_reference
737 740 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
738 741
739 742 if codes:
740 743 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
741 744 else:
742 745 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
743 746
744 747 if ref=='first_baud':
745 748 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
746 749 elif ref=='sub_baud':
747 750 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
748 751 else:
749 752 return 0
750 753
751 754 def update_pulses(self):
752 755 '''
753 756 Update pulses field
754 757 '''
755 758
756 759 km2unit = self.rc_configuration.km2unit
757 760 us2unit = self.rc_configuration.us2unit
758 761 ipp = self.rc_configuration.ipp
759 762 ntx = int(self.rc_configuration.ntx)
760 763 ipp_u = int(ipp*km2unit)
761 764 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
762 765 y = []
763 766
764 767 if self.line_type.name=='tr':
765 768 tr_params = json.loads(self.params)
766 769
767 770 if tr_params['TX_ref'] in ('0', 0):
768 771 txs = self.get_lines(line_type__name='tx')
769 772 else:
770 773 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
771 774
772 775 for tx in txs:
773 776 params = json.loads(tx.params)
774 777
775 778 if float(params['pulse_width'])==0:
776 779 continue
777 780 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
778 781 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
779 782 before = 0
780 783 after = int(self.rc_configuration.time_after*us2unit)
781 784
782 785 y_tx = self.points(ntx, ipp_u, width,
783 786 delay=delays,
784 787 before=before,
785 788 after=after,
786 789 sync=self.rc_configuration.sync)
787 790
788 791 ranges = params['range'].split(',')
789 792
790 793 if len(ranges)>0 and ranges[0]!='0':
791 794 y_tx = self.mask_ranges(y_tx, ranges)
792 795
793 796 tr_ranges = tr_params['range'].split(',')
794 797
795 798 if len(tr_ranges)>0 and tr_ranges[0]!='0':
796 799 y_tx = self.mask_ranges(y_tx, tr_ranges)
797 800
798 801 y.extend(y_tx)
799 802
800 803 self.pulses = str(y)
801 804 y = self.array_to_points(self.pulses_as_array())
802 805
803 806 elif self.line_type.name=='tx':
804 807 params = json.loads(self.params)
805 808 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
806 809 width = float(params['pulse_width'])*km2unit
807 810
808 811 if width>0:
809 812 before = int(self.rc_configuration.time_before*us2unit)
810 813 after = 0
811 814
812 815 y = self.points(ntx, ipp_u, width,
813 816 delay=delays,
814 817 before=before,
815 818 after=after,
816 819 sync=self.rc_configuration.sync)
817 820
818 821 ranges = params['range'].split(',')
819 822
820 823 if len(ranges)>0 and ranges[0]!='0':
821 824 y = self.mask_ranges(y, ranges)
822 825
823 826 elif self.line_type.name=='flip':
824 827 n = float(json.loads(self.params)['number_of_flips'])
825 828 width = n*ipp*km2unit
826 829 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
827 830
828 831 elif self.line_type.name=='codes':
829 832 params = json.loads(self.params)
830 833 tx = RCLine.objects.get(pk=params['TX_ref'])
831 834 tx_params = json.loads(tx.params)
832 835 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
833 836 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
834 837 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
835 838 codes = [self.array_to_points(code) for code in codes]
836 839 n = len(codes)
837 840
838 841 ranges = tx_params['range'].split(',')
839 842 if len(ranges)>0 and ranges[0]!='0':
840 843 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
841 844 else:
842 845 dum = tx.pulses_as_points()
843 846
844 847 for i, tup in enumerate(dum):
845 848 if tup==(0,0): continue
846 849 code = codes[i%n]
847 850 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
848 851
849 852 elif self.line_type.name=='sync':
850 853 params = json.loads(self.params)
851 854 n = ipp_u*ntx
852 855 if params['invert'] in ('1', 1):
853 856 y = [(n-1, n)]
854 857 else:
855 858 y = [(0, 1)]
856 859
857 860 elif self.line_type.name=='prog_pulses':
858 861 params = json.loads(self.params)
859 862 if int(params['periodic'])==0:
860 863 nntx = 1
861 864 nipp = ipp_u*ntx
862 865 else:
863 866 nntx = ntx
864 867 nipp = ipp_u
865 868
866 869 if 'params' in params and len(params['params'])>0:
867 870 for p in params['params']:
868 871 y_pp = self.points(nntx, nipp,
869 872 p['end']-p['begin'],
870 873 before=p['begin'])
871 874
872 875 y.extend(y_pp)
873 876
874 877 elif self.line_type.name=='windows':
875 878 params = json.loads(self.params)
876 879 if 'params' in params and len(params['params'])>0:
877 880 tx = RCLine.objects.get(pk=params['TX_ref'])
878 881 tx_params = json.loads(tx.params)
879 882 ranges = tx_params['range'].split(',')
880 883 for p in params['params']:
881 884 y_win = self.points(ntx, ipp_u,
882 885 p['resolution']*p['number_of_samples']*km2unit,
883 886 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
884 887 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
885 888
886 889
887 890 if len(ranges)>0 and ranges[0]!='0':
888 891 y_win = self.mask_ranges(y_win, ranges)
889 892
890 893 y.extend(y_win)
891 894
892 895 elif self.line_type.name=='mix':
893 896 values = self.rc_configuration.parameters.split('-')
894 897 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
895 898 modes = [value.split('|')[1] for value in values]
896 899 ops = [value.split('|')[2] for value in values]
897 900 delays = [value.split('|')[3] for value in values]
898 901 masks = [value.split('|')[4] for value in values]
899 902 mask = list('{:8b}'.format(int(masks[0])))
900 903 mask.reverse()
901 904 if mask[self.channel] in ('0', '', ' '):
902 905 y = np.zeros(confs[0].total_units, dtype=np.int8)
903 906 else:
904 907 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
905 908
906 909 for i in range(1, len(values)):
907 910 mask = list('{:8b}'.format(int(masks[i])))
908 911 mask.reverse()
909 912
910 913 if mask[self.channel] in ('0', '', ' '):
911 914 continue
912 915 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
913 916 delay = float(delays[i])*km2unit
914 917
915 918 if modes[i]=='P':
916 919 if delay>0:
917 920 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
918 921 y_temp = np.empty_like(Y)
919 922 y_temp[:delay] = 0
920 923 y_temp[delay:] = Y[:-delay]
921 924 elif delay+len(Y)>len(y):
922 925 y_new = np.zeros(delay+len(Y), dtype=np.int8)
923 926 y_new[:len(y)] = y
924 927 y = y_new
925 928 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
926 929 y_temp[-len(Y):] = Y
927 930 elif delay+len(Y)==len(y):
928 931 y_temp = np.zeros(delay+len(Y))
929 932 y_temp[-len(Y):] = Y
930 933 elif delay+len(Y)<len(y):
931 934 y_temp = np.zeros(len(y), dtype=np.int8)
932 935 y_temp[delay:delay+len(Y)] = Y
933 936 else:
934 937 y_temp = Y.copy()
935 938
936 939 if ops[i]=='OR':
937 940 y = y | y_temp
938 941 elif ops[i]=='XOR':
939 942 y = y ^ y_temp
940 943 elif ops[i]=='AND':
941 944 y = y & y_temp
942 945 elif ops[i]=='NAND':
943 946 y = y & ~y_temp
944 947 else:
945 948 y = np.concatenate([y, Y])
946 949
947 950 total = len(y)
948 951 y = self.array_to_points(y)
949 952
950 953 else:
951 954 y = []
952 955
953 956 if self.rc_configuration.total_units != total:
954 957 self.rc_configuration.total_units = total
955 958 self.rc_configuration.save()
956 959
957 960 self.pulses = str(y)
958 961 self.save()
959 962
960 963 @staticmethod
961 964 def array_to_points(X):
962 965
963 966 if X.size==0:
964 967 return []
965 968
966 969 d = X[1:]-X[:-1]
967 970
968 971 up = np.where(d==1)[0]
969 972 if X[0]==1:
970 973 up = np.concatenate((np.array([-1]), up))
971 974 up += 1
972 975
973 976 dw = np.where(d==-1)[0]
974 977 if X[-1]==1:
975 978 dw = np.concatenate((dw, np.array([len(X)-1])))
976 979 dw += 1
977 980
978 981 return [(tup[0], tup[1]) for tup in zip(up, dw)]
979 982
980 983 @staticmethod
981 984 def mask_ranges(Y, ranges):
982 985
983 986 y = [(0, 0) for __ in Y]
984 987
985 988 for index in ranges:
986 989 if '-' in index:
987 990 args = [int(a) for a in index.split('-')]
988 991 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
989 992 else:
990 993 y[int(index)-1] = Y[int(index)-1]
991 994
992 995 return y
993 996
994 997 @staticmethod
995 998 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
996 999
997 1000 delays = len(delay)
998 1001
999 1002 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1000 1003
1001 1004 return Y
@@ -1,27 +1,27
1 1 {% extends "dev_conf.html" %}
2 2 {% load static %}
3 3 {% load bootstrap3 %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-menu-actions %}
7 7 <li><a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank"><span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Pulses </a></li>
8 8 {% endblock %}
9 9
10 10 {% block extra-content %}
11 11
12 12 <div class="clearfix"></div>
13 13 <h2>RC Lines</h2>
14 <hr>
14 <br>
15 15 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
16 16 {% include "rc_lines.html" %}
17 17 </div>
18 18
19 19 {% endblock extra-content%}
20 20
21 21 {% block extra-js%}
22 22 <script type="text/javascript">
23 23 $("#bt_toggle").click(function() {
24 24 $(".panel-collapse").collapse('toggle')
25 25 });
26 26 </script>
27 27 {% endblock %} No newline at end of file
@@ -1,23 +1,23
1 1 from django.conf.urls import url
2 2
3 3 from apps.rc import views
4 4
5 5 urlpatterns = (
6 6 url(r'^(?P<conf_id>-?\d+)/$', views.conf, name='url_rc_conf'),
7 7 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'),
8 8 url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'),
9 9 url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'),
10 10 url(r'^(?P<conf_id>-?\d+)/plot2/$', views.plot_pulses2, name='url_plot_rc_pulses2'),
11 11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
12 12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
13
13 url(r'^(?P<conf_id>-?\d+)/raw/$', views.conf_raw, name='url_raw_rc_conf'),
14 14 url(r'^(?P<conf_id>-?\d+)/add_line/$', views.add_line, name='url_add_rc_line'),
15 15 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/$', views.add_line, name='url_add_rc_line'),
16 16 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/code/(?P<code_id>-?\d+)/$', views.add_line, name='url_add_rc_line_code'),
17 17 url(r'^(?P<conf_id>-?\d+)/update_position/$', views.update_lines_position, name='url_update_rc_lines_position'),
18 18 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/delete/$', views.remove_line, name='url_remove_rc_line'),
19 19 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/add_subline/$', views.add_subline, name='url_add_rc_subline'),
20 20 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/$', views.edit_codes, name='url_edit_rc_codes'),
21 21 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/(?P<code_id>-?\d+)/$', views.edit_codes, name='url_edit_rc_codes'),
22 22 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/subline/(?P<subline_id>-?\d+)/delete/$', views.remove_subline, name='url_remove_rc_subline'),
23 23 )
@@ -1,244 +1,243
1 1 '''
2 2 '''
3 3
4 4 import json
5 5
6 6 from apps.main.utils import Params
7 7
8 8 def parse_range(s):
9 9
10 10 vars = ('TXA,', 'A,', 'TXB,', 'B,', 'TXA', 'TXB', 'A', 'B')
11 11
12 12 for var in vars:
13 13 if var in s:
14 14 s = s.replace(var, '')
15 15 if 'A' in var:
16 16 ref = 'TXA'
17 17 else:
18 18 ref = 'TXB'
19 19 return ref, s
20 20
21 21 return '0', s
22 22
23 23
24 24 class RCFile(object):
25 25 '''
26 26 Class to handle Radar controller configuration files
27 27 '''
28 28
29 29 def __init__(self, f=None):
30 print dir(f)
31 30 self.data = {}
32 31 self.lines = []
33 32 self.line = ''
34 33 if isinstance(f, str):
35 34 self.f = open(f)
36 35 self.name = f.split('/')[-1]
37 36 elif hasattr(f, 'read'):
38 37 self.f = f
39 38 self.name = f.name.split('/')[-1]
40 39 else:
41 40 self.f = f
42 41 self.name = None
43 42
44 43 if self.f:
45 44 if 'racp' in self.name:
46 45 self.parse_racp()
47 46 elif 'dat' in self.name:
48 47 self.parse_dat()
49 48 elif 'json' in self.name:
50 49 self.data = json.load(self.f)
51 50
52 51 self.f.close()
53 52
54 53 def get_line_parameters(self, data, line):
55 54
56 55 line_params = {}
57 56 for label in data:
58 57 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
59 58 line_params[label] = data[label]
60 59 return line_params
61 60
62 61 def parse_racp(self):
63 62
64 63 data = {}
65 64 raw_data = [s.strip() for s in self.f.readlines()]
66 65
67 66 for line in raw_data:
68 67 if line and '=' in line:
69 68 label, value = line.strip().split('=')
70 69 data[label] = value
71 70
72 71 self.data['id'] = '1'
73 72 self.data['device_type'] = 'rc'
74 73 self.data['experiment_type'] = data['EXPERIMENT TYPE']
75 74 self.data['header_version'] = data['HEADER VERSION']
76 self.data['name'] = data['EXPERIMENT NAME']
75 self.data['label'] = data['EXPERIMENT NAME']
77 76 self.data['ipp'] = float(data['IPP'])
78 77 self.data['ntx'] = int(data['NTX'])
79 78
80 79 if 'CLOCK DIVIDER' in data:
81 80 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
82 81 else:
83 82 self.data['clock_divider'] = 1
84 83 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
85 84 self.data['clock'] = float(data['RELOJ'])
86 85 self.data['time_before'] = int(data['TR_BEFORE'])
87 86 self.data['time_after'] = int(data['TR_AFTER'])
88 87
89 88 if 'SYNCHRO DELAY' in data:
90 89 self.data['sync'] = int(data['SYNCHRO DELAY'])
91 90 else:
92 91 self.data['sync'] = 0
93 92
94 93 self.data['lines'] = []
95 94
96 95 if 'SAMPLING REFERENCE' in data:
97 96 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
98 97 self.data['sampling_reference'] = 'first_baud'
99 98 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
100 99 self.data['sampling_reference'] = 'sub_baud'
101 100 else:
102 101 self.data['sampling_reference'] = 'none'
103 102
104 103 self.data['lines'].append('10')
105 104
106 105 #Add TX's lines
107 106 if 'TXA' in data:
108 107 line = {'line_type':'tx', 'id':'11', 'name':'TXA',
109 108 'params':{'pulse_width':data['TXA'], 'delays':'0', 'range':'0'}}
110 109 if 'Pulse selection_TXA' in data:
111 110 line['params']['range'] = data['Pulse selection_TXA']
112 111 self.data['lines'].append('11')
113 112 self.lines.append(line)
114 113
115 114 if 'TXB' in data:
116 115 line = {'line_type':'tx', 'id':'12', 'name':'TXB',
117 116 'params':{'pulse_width':data['TXB'], 'delays':'0', 'range':'0'}}
118 117 if 'Pulse selection_TXB' in data:
119 118 line['params']['range'] = data['Pulse selection_TXB']
120 119
121 120 if 'Number of Taus' in data:
122 121 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
123 122 line['params']['delays'] = ','.join(delays)
124 123
125 124 self.data['lines'].append('12')
126 125 self.lines.append(line)
127 126
128 127 #Add TR line
129 128 line = {'line_type':'tr', 'id':'10', 'name':'TR',
130 129 'params':{'TX_ref':'0', 'range':'0'}}
131 130 if 'Pulse selection_TR' in data:
132 131 ref, rng = parse_range(data['Pulse selection_TR'])
133 132 line['params']['range'] = rng if rng else '0'
134 133 if ref=='TXA':
135 134 line['params']['TX_ref'] = '11'
136 135 elif ref=='TXB':
137 136 line['params']['TX_ref'] = '12'
138 137
139 138 self.lines.append(line)
140 139
141 140 #Add Other lines (4-6)
142 141 for n in range(4, 7):
143 142 id = '{:2d}'.format(10*n)
144 143 params = self.get_line_parameters(data, n)
145 144 labels = params.keys()
146 145
147 146 if 'L%d_FLIP' % n in labels:
148 147 line = {'line_type':'flip', 'id':id,
149 148 'params':{'number_of_flips':data['L%d_FLIP' % n]}}
150 149 elif 'Code Type' in data and n==4:
151 150 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type']}}
152 151 if data['L%d_REFERENCE' % n]=='TXA':
153 152 line['params']['TX_ref'] = '11'
154 153 else:
155 154 line['params']['TX_ref'] = '12'
156 155 if 'Number of Codes' in data:
157 156 line['params']['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
158 157 elif 'Code Type (Line %d)' % n in labels:
159 158 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type (Line %d)' % n]}}
160 159 if data['L%d_REFERENCE' % n]=='TXA':
161 160 line['params']['TX_ref'] = '11'
162 161 else:
163 162 line['params']['TX_ref'] = '12'
164 163 if 'Number of Codes (Line %d)' % n in data:
165 164 line['params']['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
166 165 elif 'Sampling Windows (Line %d)' % n in data:
167 166 line = {'line_type':'windows', 'id':id, 'params':{}}
168 167 if data['L%d_REFERENCE' % n]=='TXA':
169 168 line['params']['TX_ref'] = '11'
170 169 else:
171 170 line['params']['TX_ref'] = '12'
172 171 windows = []
173 172 for w in range(int(data['Sampling Windows (Line %d)' % n])):
174 173 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
175 174 'resolution':float(data['L%d_DH(%d)' % (n, w)]),
176 175 'number_of_samples':int(float(data['L%d_NSA(%d)' % (n, w)])),
177 176 'last_height':float(data['L%d_DH(%d)' % (n, w)])*(int(float(data['L%d_NSA(%d)' % (n, w)]))-1)+float(data['L%d_H0(%d)' % (n, w)])
178 177 }
179 178 )
180 179 line['params']['params'] = windows
181 180 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
182 181 line = {'line_type':'sync', 'id':id, 'params':{'invert':0}}
183 182 elif 'L%d Number Of Portions' % n in labels:
184 183 line = {'line_type':'prog_pulses', 'id':id, 'params':{}}
185 184 if 'L%s Portions IPP Periodic' % n in data:
186 185 line['params']['periodic'] = '1' if data['L%s Portions IPP Periodic' % n]=='YES' else '0'
187 186 portions = []
188 187 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
189 188 for w in range(int(data['L%d Number Of Portions' % n])):
190 189 begin = float(raw_data[x+1+2*w].split('=')[-1])
191 190 end = float(raw_data[x+2+2*w].split('=')[-1])
192 191 portions.append({'begin':int(begin),
193 192 'end':int(end)}
194 193 )
195 194 line['params']['params'] = portions
196 195 elif 'FLIP1' in data and n==5:
197 196 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP1']}}
198 197 elif 'FLIP2' in data and n==6:
199 198 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP2']}}
200 199 else:
201 200 line = {'line_type':'none', 'id':id, 'params':{}}
202 201
203 202 self.data['lines'].append(id)
204 203 self.lines.append(line)
205 204
206 205 #Add line 7 (windows)
207 206 if 'Sampling Windows' in data:
208 207 line = {'line_type':'windows', 'id':'17', 'params':{}}
209 208 if data['L7_REFERENCE']=='TXA':
210 209 line['params']['TX_ref'] = '11'
211 210 else:
212 211 line['params']['TX_ref'] = '12'
213 212 windows = []
214 213 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
215 214 for w in range(int(data['Sampling Windows'])):
216 215 h0 = raw_data[x+1+3*w].split('=')[-1]
217 216 nsa = raw_data[x+2+3*w].split('=')[-1]
218 217 dh = raw_data[x+3+3*w].split('=')[-1]
219 218 windows.append({'first_height':float(h0),
220 219 'number_of_samples':int(nsa),
221 220 'resolution':float(dh),
222 221 'last_height':float(h0)+float(dh)*(int(nsa)-1)}
223 222 )
224 223 line['params']['params'] = windows
225 224 self.data['lines'].append('17')
226 225 self.lines.append(line)
227 226
228 227 #Add line 8 (synchro inverted)
229 228 self.data['lines'].append('18')
230 229 self.lines.append({'line_type':'sync', 'id':'18', 'params':{'invert':1}})
231 230
232 231 return
233 232
234 233 def parse_dat(self):
235 234 pass
236 235
237 236 def to_dict(self):
238 237
239 238 out = Params()
240 239 out.add(self.data, 'configurations')
241 240 for line_data in self.lines:
242 241 out.add(line_data, 'lines')
243 242
244 243 return out.data
@@ -1,401 +1,407
1 1
2 2 import json
3 3
4 4 from django.contrib import messages
5 5 from django.utils.safestring import mark_safe
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 8
8 9 from apps.main.models import Experiment, Device
9 10 from apps.main.views import sidebar
10 11
11 12 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
12 13 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13 14
14 15
15 16 def conf(request, conf_id):
16 17
17 18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18 19
19 20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 21
21 22 for line in lines:
22 23 params = json.loads(line.params)
23 24 line.form = RCLineViewForm(extra_fields=params, line=line)
24 25 if 'params' in params:
25 26 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
26 27
27 28 kwargs = {}
28 29 kwargs['dev_conf'] = conf
29 30 kwargs['rc_lines'] = lines
30 kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
31 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
31 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
32 'time_before', 'time_after', 'sync', 'sampling_reference',
33 'control_tx', 'control_sw']
32 34
33 kwargs['title'] = 'RC Configuration'
34 kwargs['suptitle'] = 'Details'
35 kwargs['title'] = 'Configuration'
36 kwargs['suptitle'] = 'Detail'
35 37
36 38 kwargs['button'] = 'Edit Configuration'
37 39 ###### SIDEBAR ######
38 40 kwargs.update(sidebar(conf=conf))
39 41
40 42 return render(request, 'rc_conf.html', kwargs)
41 43
42
44 @login_required
43 45 def conf_edit(request, conf_id):
44 46
45 47 conf = get_object_or_404(RCConfiguration, pk=conf_id)
46 48
47 49 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48 50
49 51 for line in lines:
50 52 params = json.loads(line.params)
51 53 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
52 54 line.subform = False
53 55
54 56 if 'params' in params:
55 57 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
56 58 line.subform = True
57 59
58 60 if request.method=='GET':
59 61
60 62 form = RCConfigurationForm(instance=conf)
61 63
62 64 elif request.method=='POST':
63 65
64 66 line_data = {}
65 67 conf_data = {}
66 68 extras = []
67 69
68 70 #classified post fields
69 71 for label,value in request.POST.items():
70 72 if label=='csrfmiddlewaretoken':
71 73 continue
72 74
73 75 if label.count('|')==0:
74 76 conf_data[label] = value
75 77 continue
76 78
77 79 elif label.split('|')[0]!='-1':
78 80 extras.append(label)
79 81 continue
80 82
81 83 x, pk, name = label.split('|')
82 84
83 85 if name=='codes':
84 86 value = [s for s in value.split('\r\n') if s]
85 87
86 88 if pk in line_data:
87 89 line_data[pk][name] = value
88 90 else:
89 91 line_data[pk] = {name:value}
90 92
91 93 #update conf
92 94 form = RCConfigurationForm(conf_data, instance=conf)
93 95
94 96 if form.is_valid():
95 97
96 98 form.save()
97 99
98 100 #update lines fields
99 101 extras.sort()
100 102 for label in extras:
101 103 x, pk, name = label.split('|')
102 104 if pk not in line_data:
103 105 line_data[pk] = {}
104 106 if 'params' not in line_data[pk]:
105 107 line_data[pk]['params'] = []
106 108 if len(line_data[pk]['params'])<int(x)+1:
107 109 line_data[pk]['params'].append({})
108 110 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
109 111
110 112 for pk, params in line_data.items():
111 113 line = RCLine.objects.get(pk=pk)
112 114 if line.line_type.name in ('windows', 'prog_pulses'):
113 115 if 'params' not in params:
114 116 params['params'] = []
115 117 line.params = json.dumps(params)
116 118 line.save()
117 119
118 120 #update pulses field
119 121 conf.update_pulses()
120 122
121 123 messages.success(request, 'RC Configuration successfully updated')
122 124
123 125 return redirect(conf.get_absolute_url())
124 126
125 127 kwargs = {}
126 128 kwargs['dev_conf'] = conf
127 129 kwargs['form'] = form
128 130 kwargs['rc_lines'] = lines
129 131 kwargs['edit'] = True
130 132
131 133 kwargs['title'] = 'RC Configuration'
132 134 kwargs['suptitle'] = 'Edit'
133 135 kwargs['button'] = 'Update'
134 kwargs['previous'] = conf.get_absolute_url()
135 136
136 137 return render(request, 'rc_conf_edit.html', kwargs)
137 138
138 139
139 140 def add_line(request, conf_id, line_type_id=None, code_id=None):
140 141
141 142 conf = get_object_or_404(RCConfiguration, pk=conf_id)
142 143
143 144 if request.method=='GET':
144 145 if line_type_id:
145 146 line_type = get_object_or_404(RCLineType, pk=line_type_id)
146 147
147 148 if code_id:
148 149 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
149 150 extra_fields=json.loads(line_type.params))
150 151 else:
151 152 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
152 153 extra_fields=json.loads(line_type.params))
153 154 else:
154 155 line_type = {'id':0}
155 156 form = RCLineForm(initial={'rc_configuration':conf_id})
156 157
157 158 if request.method=='POST':
158 159
159 160 line_type = get_object_or_404(RCLineType, pk=line_type_id)
160 161 form = RCLineForm(request.POST,
161 162 extra_fields=json.loads(line_type.params))
162 163
163 164 if form.is_valid():
164 165 form.save()
165 166 form.instance.update_pulses()
166 167 return redirect('url_edit_rc_conf', conf.id)
167 168
168 169 kwargs = {}
169 170 kwargs['form'] = form
170 171 kwargs['title'] = 'RC Configuration'
171 172 kwargs['suptitle'] = 'Add Line'
172 173 kwargs['button'] = 'Add'
173 174 kwargs['previous'] = conf.get_absolute_url_edit()
174 175 kwargs['dev_conf'] = conf
175 176 kwargs['line_type'] = line_type
176 177
177 178 return render(request, 'rc_add_line.html', kwargs)
178 179
179 180 def edit_codes(request, conf_id, line_id, code_id=None):
180 181
181 182 conf = get_object_or_404(RCConfiguration, pk=conf_id)
182 183 line = get_object_or_404(RCLine, pk=line_id)
183 184 params = json.loads(line.params)
184 185
185 186 if request.method=='GET':
186 187 if code_id:
187 188 code = get_object_or_404(RCLineCode, pk=code_id)
188 189 form = RCLineCodesForm(instance=code)
189 190 else:
190 191 initial = {'code': params['code'],
191 192 'codes': params['codes'] if 'codes' in params else [],
192 193 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
193 194 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
194 195 }
195 196 form = RCLineCodesForm(initial=initial)
196 197
197 198 if request.method=='POST':
198 199 form = RCLineCodesForm(request.POST)
199 200 if form.is_valid():
200 201 params['code'] = request.POST['code']
201 202 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
202 203 line.params = json.dumps(params)
203 204 line.save()
204 205 messages.success(request, 'Line: "%s" has been updated.' % line)
205 206 return redirect('url_edit_rc_conf', conf.id)
206 207
207 208 kwargs = {}
208 209 kwargs['form'] = form
209 210 kwargs['title'] = line
210 211 kwargs['suptitle'] = 'Edit'
211 212 kwargs['button'] = 'Update'
212 213 kwargs['dev_conf'] = conf
213 214 kwargs['previous'] = conf.get_absolute_url_edit()
214 215 kwargs['line'] = line
215 216
216 217 return render(request, 'rc_edit_codes.html', kwargs)
217 218
218 219 def add_subline(request, conf_id, line_id):
219 220
220 221 conf = get_object_or_404(RCConfiguration, pk=conf_id)
221 222 line = get_object_or_404(RCLine, pk=line_id)
222 223
223 224 if request.method == 'POST':
224 225 if line:
225 226 params = json.loads(line.params)
226 227 subparams = json.loads(line.line_type.params)
227 228 if 'params' in subparams:
228 229 dum = {}
229 230 for key, value in subparams['params'].items():
230 231 dum[key] = value['value']
231 232 params['params'].append(dum)
232 233 line.params = json.dumps(params)
233 234 line.save()
234 235 return redirect('url_edit_rc_conf', conf.id)
235 236
236 237 kwargs = {}
237 238
238 239 kwargs['title'] = 'Add new'
239 240 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
240 241
241 242 return render(request, 'confirm.html', kwargs)
242 243
243 244 def remove_line(request, conf_id, line_id):
244 245
245 246 conf = get_object_or_404(RCConfiguration, pk=conf_id)
246 247 line = get_object_or_404(RCLine, pk=line_id)
247 248
248 249 if request.method == 'POST':
249 250 if line:
250 251 try:
251 252 channel = line.channel
252 253 line.delete()
253 254 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
254 255 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
255 256 l.channel = l.channel-1
256 257 l.save()
257 258 messages.success(request, 'Line: "%s" has been deleted.' % line)
258 259 except:
259 260 messages.error(request, 'Unable to delete line: "%s".' % line)
260 261
261 262 return redirect('url_edit_rc_conf', conf.id)
262 263
263 264 kwargs = {}
264 265
265 266 kwargs['object'] = line
266 267 kwargs['delete'] = True
267 268 kwargs['title'] = 'Delete'
268 269 kwargs['suptitle'] = 'Line'
269 270 kwargs['previous'] = conf.get_absolute_url_edit()
270 271 return render(request, 'confirm.html', kwargs)
271 272
272 273
273 274 def remove_subline(request, conf_id, line_id, subline_id):
274 275
275 276 conf = get_object_or_404(RCConfiguration, pk=conf_id)
276 277 line = get_object_or_404(RCLine, pk=line_id)
277 278
278 279 if request.method == 'POST':
279 280 if line:
280 281 params = json.loads(line.params)
281 282 params['params'].remove(params['params'][int(subline_id)-1])
282 283 line.params = json.dumps(params)
283 284 line.save()
284 285
285 286 return redirect('url_edit_rc_conf', conf.id)
286 287
287 288 kwargs = {}
288 289
289 290 kwargs['object'] = line
290 291 kwargs['object_name'] = line.line_type.name
291 292 kwargs['delete_view'] = True
292 293 kwargs['title'] = 'Confirm delete'
293 294
294 295 return render(request, 'confirm.html', kwargs)
295 296
296 297
297 298 def update_lines_position(request, conf_id):
298 299
299 300 conf = get_object_or_404(RCConfiguration, pk=conf_id)
300 301
301 302 if request.method=='POST':
302 303 ch = 0
303 304 for item in request.POST['items'].split('&'):
304 305 line = RCLine.objects.get(pk=item.split('=')[-1])
305 306 line.channel = ch
306 307 line.save()
307 308 ch += 1
308 309
309 310 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
310 311
311 312 for line in lines:
312 313 params = json.loads(line.params)
313 314 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
314 315
315 316 if 'params' in params:
316 317 line.subform = True
317 318 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
318 319
319 320 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
320 321 data = {'html': html.content.decode('utf8')}
321 322
322 323 return HttpResponse(json.dumps(data), content_type="application/json")
323 324 return redirect('url_edit_rc_conf', conf.id)
324 325
325 326
326 327 def import_file(request, conf_id):
327 328
328 329 conf = get_object_or_404(RCConfiguration, pk=conf_id)
329 330 if request.method=='POST':
330 331 form = RCImportForm(request.POST, request.FILES)
331 332 if form.is_valid():
332 333 try:
333 334 data = conf.import_from_file(request.FILES['file_name'])
334 335 conf.dict_to_parms(data)
335 336 conf.update_pulses()
336 337 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
337 338 return redirect(conf.get_absolute_url_edit())
338 339
339 340 except Exception as e:
340 341 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
341 342 else:
342 343 messages.warning(request, 'Your current configuration will be replaced')
343 344 form = RCImportForm()
344 345
345 346 kwargs = {}
346 347 kwargs['form'] = form
347 348 kwargs['title'] = 'RC Configuration'
348 349 kwargs['suptitle'] = 'Import file'
349 350 kwargs['button'] = 'Upload'
350 351 kwargs['previous'] = conf.get_absolute_url()
351 352
352 353 return render(request, 'rc_import.html', kwargs)
353 354
354 355
355 356 def plot_pulses(request, conf_id):
356 357
357 358 conf = get_object_or_404(RCConfiguration, pk=conf_id)
358 359 km = True if 'km' in request.GET else False
359 360
360 361 script, div = conf.plot_pulses(km=km)
361 362
362 363 kwargs = {}
363 364 kwargs['no_sidebar'] = True
364 365 kwargs['title'] = 'RC Pulses'
365 366 kwargs['suptitle'] = conf.name
366 367 kwargs['div'] = mark_safe(div)
367 368 kwargs['script'] = mark_safe(script)
368 369 kwargs['units'] = conf.km2unit
369 370 kwargs['kms'] = 1/conf.km2unit
370 371
371 372 if km:
372 373 kwargs['km_selected'] = True
373 374
374 375 if 'json' in request.GET:
375 376 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
376 377 else:
377 378 return render(request, 'rc_pulses.html', kwargs)
378 379
379 380 def plot_pulses2(request, conf_id):
380 381
381 382 conf = get_object_or_404(RCConfiguration, pk=conf_id)
382 383 km = True if 'km' in request.GET else False
383 384
384 385 script, div = conf.plot_pulses2(km=km)
385 386
386 387 kwargs = {}
387 388 kwargs['no_sidebar'] = True
388 389 kwargs['title'] = 'RC Pulses'
389 390 kwargs['suptitle'] = conf.name
390 391 kwargs['div'] = mark_safe(div)
391 392 kwargs['script'] = mark_safe(script)
392 393 kwargs['units'] = conf.km2unit
393 394 kwargs['kms'] = 1/conf.km2unit
394 395
395 396 if km:
396 397 kwargs['km_selected'] = True
397 398
398 399 if 'json' in request.GET:
399 400 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
400 401 else:
401 402 return render(request, 'rc_pulses.html', kwargs)
403
404 def conf_raw(request, conf_id):
405 conf = get_object_or_404(RCConfiguration, pk=conf_id)
406 raw = conf.write_device(raw=True)
407 return HttpResponse(raw, content_type='application/json') No newline at end of file
@@ -1,66 +1,68
1 1 version: '2'
2 2 services:
3 3 # Django app
4 4 web:
5 5 container_name: 'radarsys'
6 6 build: .
7 7 restart: always
8 8 image: radarsys
9 9 command: gunicorn radarsys.wsgi:application -w 2 -b :8000
10 10 # command: python manage.py runserver 0.0.0.0:8030
11 11 # ports:
12 12 # - 8030:8030
13 13 env_file: .env
14 14
15 15 links:
16 16 - redis
17 17 - postgres
18 18 volumes:
19 19 - './:/radarsys'
20 20 - '${DOCKER_DATA}/static:/radarsys/static'
21 21 depends_on:
22 22 - redis
23 23 - postgres
24 24
25 25 redis:
26 26 container_name: 'radarsys-redis'
27 27 image: 'redis:3.2-alpine'
28 28 volumes:
29 29 - '${DOCKER_DATA}/redis:/data'
30 30
31 31 celery_worker:
32 32 container_name: 'radarsys-celery'
33 33 image: radarsys
34 34 env_file: .env
35 35 command: celery -A radarsys worker -l info
36 36 volumes_from:
37 37 - web
38 38 depends_on:
39 39 - web
40 40
41 41 # PostgreSQL
42 42 postgres:
43 43 container_name: 'radarsys-postgres'
44 44 build: ./postgres/
45 45 volumes:
46 46 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
47 47 - pgdata:/var/lib/postgresql/data
48 # ports:
49 # - 5432:5432
48 50 env_file: .env
49 51
50 52 # Web Server
51 53 nginx:
52 54 container_name: 'radarsys-nginx'
53 55 restart: always
54 56 build: ./nginx/
55 57 ports:
56 58 - '8030:8030'
57 59 volumes_from:
58 60 - web
59 61 links:
60 62 - web:web
61 63 depends_on:
62 64 - web
63 65
64 66 volumes:
65 67 pgdata:
66 68 driver: local
@@ -1,136 +1,140
1 1 """
2 2 Django settings for radarsys project.
3 3
4 4 Generated by 'django-admin startproject' using Django 1.8.6.
5 5
6 6 For more information on this file, see
7 7 https://docs.djangoproject.com/en/1.8/topics/settings/
8 8
9 9 For the full list of settings and their values, see
10 10 https://docs.djangoproject.com/en/1.8/ref/settings/
11 11 """
12 12
13 13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 14 import os
15 15
16 16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 17
18 18 # Quick-start development settings - unsuitable for production
19 19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
20 20
21 21 # SECURITY WARNING: keep the secret key used in production secret!
22 22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
23 23
24 24 # SECURITY WARNING: don't run with debug turned on in production!
25 25 DEBUG = True
26 26
27 27 ALLOWED_HOSTS = ['*']
28 28
29 29 # Application definition
30 30
31 31 INSTALLED_APPS = (
32 32 'django.contrib.admin',
33 33 'django.contrib.auth',
34 34 'django.contrib.contenttypes',
35 35 'django.contrib.sessions',
36 36 'django.contrib.messages',
37 37 'django.contrib.staticfiles',
38 38 'bootstrap3',
39 39 'polymorphic',
40 40 'apps.accounts',
41 41 'apps.main',
42 42 'apps.misc',
43 43 'apps.rc',
44 44 'apps.dds',
45 45 'apps.jars',
46 46 'apps.usrp',
47 47 'apps.abs',
48 48 'apps.cgs',
49 49 )
50 50
51 51 MIDDLEWARE_CLASSES = (
52 52 'django.contrib.sessions.middleware.SessionMiddleware',
53 53 'django.middleware.common.CommonMiddleware',
54 54 'django.middleware.csrf.CsrfViewMiddleware',
55 55 'django.contrib.auth.middleware.AuthenticationMiddleware',
56 56 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
57 57 'django.contrib.messages.middleware.MessageMiddleware',
58 58 'django.middleware.clickjacking.XFrameOptionsMiddleware',
59 59 'django.middleware.security.SecurityMiddleware',
60 60 )
61 61
62 62 ROOT_URLCONF = 'radarsys.urls'
63 63
64 64 TEMPLATES = [
65 65 {
66 66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
67 67 'DIRS': [os.path.join(BASE_DIR, "templates").replace('\\', '/'),],
68 68 'APP_DIRS': True,
69 69 'OPTIONS': {
70 70 'context_processors': [
71 71 'django.template.context_processors.debug',
72 72 'django.template.context_processors.request',
73 73 'django.contrib.auth.context_processors.auth',
74 74 'django.contrib.messages.context_processors.messages',
75 75 ],
76 76 },
77 77 },
78 78 ]
79 79
80 80 WSGI_APPLICATION = 'radarsys.wsgi.application'
81 81
82 82
83 83 # Database
84 84 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
85 85
86 86 DATABASES = {
87 87 'default': {
88 'ENGINE': 'django.db.backends.postgresql_psycopg2',
89 'NAME': os.environ.get('POSTGRES_DB_NAME', 'radarsys'),
90 'USER': os.environ.get('POSTGRES_USER', 'docker'),
91 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'docker'),
92 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'postgres'),
93 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', ''),
88 'ENGINE': 'django.db.backends.sqlite3',
89 'NAME': 'radarsys.sqlite',
94 90 }
91 # 'default': {
92 # 'ENGINE': 'django.db.backends.postgresql_psycopg2',
93 # 'NAME': os.environ.get('POSTGRES_DB_NAME', 'radarsys'),
94 # 'USER': os.environ.get('POSTGRES_USER', 'docker'),
95 # 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'docker'),
96 # 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'postgres'),
97 # 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', ''),
98 # }
95 99 }
96 100
97 101 # Internationalization
98 102 # https://docs.djangoproject.com/en/1.8/topics/i18n/
99 103
100 104 LANGUAGE_CODE = 'en-us'
101 105
102 106 TIME_ZONE = os.environ.get('TZ', 'UTC')
103 107
104 108 USE_I18N = True
105 109
106 110 USE_L10N = True
107 111
108 112 USE_TZ = False
109 113
110 114 # Static files (CSS, JavaScript, Images)
111 115 # https://docs.djangoproject.com/en/1.8/howto/static-files/
112 116
113 117 MEDIA_URL = '/media/'
114 118 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
115 119
116 120 STATIC_URL = '/static/'
117 121 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
118 122
119 123 STATICFILES_FINDERS = (
120 124 'django.contrib.staticfiles.finders.FileSystemFinder',
121 125 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
122 126 )
123 127
124 128 # Celery stuff
125 129 REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
126 130 REDIS_PORT = os.environ.get('REDIS_PORT', 6379)
127 131
128 132 BROKER_TRANSPORT = 'redis'
129 133 BROKER_URL = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
130 134
131 135 CELERY_RESULT_BACKEND = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
132 136 CELERY_BROKER_TRANSPORT = BROKER_URL
133 137 CELERY_ACCEPT_CONTENT = ['application/json']
134 138 CELERY_TASK_SERIALIZER = 'json'
135 139 CELERY_RESULT_SERIALIZER = 'json'
136 140 CELERY_ENABLE_UTC = False No newline at end of file
@@ -1,27 +0,0
1 {% load bootstrap3 %}
2 {% load static %}
3 {% load main_tags %}
4
5 {% block content %}
6
7 {% block menu-actions %}
8
9 {% endblock %}
10
11 <table class="table table-bordered">
12
13 <tr> <th>Clock in (MHz)</th><td>{{filter.clock}}</td> </tr>
14 <tr> <th>Multiplier</th><td>{{filter.mult}}</td> </tr>
15 <tr> <th>Frequency (MHz)</th><td>{{filter.fch}}</td> </tr>
16 <tr> <th>Frequency (Decimal)</th><td>{{filter.fch_decimal}}</td> </tr>
17 <tr> <th>Filter 2</th><td>{{filter.filter_2}}</td> </tr>
18 <tr> <th>Filter 5</th><td>{{filter.filter_5}}</td> </tr>
19 <tr> <th>FIR Filter</th><td>{{filter.filter_fir}}</td> </tr>
20
21 </table>
22
23
24 {% block extra-content %}
25 {% endblock %}
26
27 {% endblock %}
@@ -1,29 +0,0
1 {% load bootstrap3 %}
2 {% load static %}
3 {% load main_tags %}
4
5 {% block content %}
6 <form class="form" method="post">
7 {% csrf_token %}
8 {% bootstrap_form filter_form layout='horizontal' size='medium' %}
9 <div style="clear: both;"></div>
10 <br>
11 <div class="pull-right">
12 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
13 <button type="button" class="btn btn-primary" id="bt_change_filter">Change Filter</button>
14 <button type="submit" class="btn btn-primary">{{button}}</button>
15 </div>
16 </form>
17 {% endblock %}
18
19 {% block extra-js%}
20 <script src="{% static 'js/filters.js' %}"></script>
21
22 <script type="text/javascript">
23
24 $("#bt_change_filter").click(function() {
25 document.location = "{% url 'url_change_jars_filter' id_dev %}";
26 });
27
28 </script>
29 {% endblock %}
@@ -1,11 +0,0
1 @import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700");/*!
2 * bootswatch v3.3.6
3 * Homepage: http://bootswatch.com
4 * Copyright 2012-2016 Thomas Park
5 * Licensed under MIT
6 * Based on Bootstrap
7 *//*!
8 * Bootstrap v3.3.6 (http://getbootstrap.com)
9 * Copyright 2011-2015 Twitter, Inc.
10 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11 *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-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:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}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{border:0;padding: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-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-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}.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.woff2') format('woff2'),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:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.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"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-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:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:1.846;color:#666666;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#2196f3;text-decoration:none}a:hover,a:focus{color:#0a6ebd;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:3px}.img-thumbnail{padding:4px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:23px;margin-bottom:23px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;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}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:400;line-height:1.1;color:#444444}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:normal;line-height:1;color:#bbbbbb}h1,.h1,h2,.h2,h3,.h3{margin-top:23px;margin-bottom:11.5px}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:11.5px;margin-bottom:11.5px}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:56px}h2,.h2{font-size:45px}h3,.h3{font-size:34px}h4,.h4{font-size:24px}h5,.h5{font-size:20px}h6,.h6{font-size:14px}p{margin:0 0 11.5px}.lead{margin-bottom:23px;font-size:14px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:19.5px}}small,.small{font-size:92%}mark,.mark{background-color:#ffe0b2;padding:.2em}.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:#bbbbbb}.text-primary{color:#2196f3}a.text-primary:hover,a.text-primary:focus{color:#0c7cd5}.text-success{color:#4caf50}a.text-success:hover,a.text-success:focus{color:#3d8b40}.text-info{color:#9c27b0}a.text-info:hover,a.text-info:focus{color:#771e86}.text-warning{color:#ff9800}a.text-warning:hover,a.text-warning:focus{color:#cc7a00}.text-danger{color:#e51c23}a.text-danger:hover,a.text-danger:focus{color:#b9151b}.bg-primary{color:#fff;background-color:#2196f3}a.bg-primary:hover,a.bg-primary:focus{background-color:#0c7cd5}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#e1bee7}a.bg-info:hover,a.bg-info:focus{background-color:#d099d9}.bg-warning{background-color:#ffe0b2}a.bg-warning:hover,a.bg-warning:focus{background-color:#ffcb7f}.bg-danger{background-color:#f9bdbb}a.bg-danger:hover,a.bg-danger:focus{background-color:#f5908c}.page-header{padding-bottom:10.5px;margin:46px 0 23px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:11.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:23px}dt,dd{line-height:1.846}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #bbbbbb}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:11.5px 23px;margin:0 0 23px;font-size:16.25px;border-left:5px solid #eeeeee}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.846;color:#bbbbbb}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;text-align:right}.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:23px;font-style:normal;line-height:1.846}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:3px}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:11px;margin:0 0 11.5px;font-size:12px;line-height:1.846;word-break:break-all;word-wrap:break-word;color:#212121;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:3px}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{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-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-left:15px;padding-right: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:#bbbbbb;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:23px}.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.846;vertical-align:top;border-top:1px solid #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.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 #dddddd}.table .table{background-color:#ffffff}.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 #dddddd}.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 #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.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:#e1bee7}.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:#d8abe0}.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:#ffe0b2}.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:#ffd699}.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:#f9bdbb}.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:#f7a6a4}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:17.25px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd}.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{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:23px;font-size:19.5px;line-height:inherit;color:#212121;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}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:13px;line-height:1.846;color:#666666}.form-control{display:block;width:100%;height:37px;padding:6px 16px;font-size:13px;line-height:1.846;color:#666666;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-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,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#bbbbbb;opacity:1}.form-control:-ms-input-placeholder{color:#bbbbbb}.form-control::-webkit-input-placeholder{color:#bbbbbb}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:transparent;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:37px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:45px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:23px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;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;min-height:36px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:35px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}select.input-lg{height:45px;line-height:45px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}.form-group-lg select.form-control{height:45px;line-height:45px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:45px;min-height:40px;padding:11px 16px;font-size:17px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:46.25px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:37px;height:37px;line-height:37px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:45px;height:45px;line-height:45px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.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:#4caf50}.has-success .form-control{border-color:#4caf50;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#3d8b40;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94}.has-success .input-group-addon{color:#4caf50;border-color:#4caf50;background-color:#dff0d8}.has-success .form-control-feedback{color:#4caf50}.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:#ff9800}.has-warning .form-control{border-color:#ff9800;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#cc7a00;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166}.has-warning .input-group-addon{color:#ff9800;border-color:#ff9800;background-color:#ffe0b2}.has-warning .form-control-feedback{color:#ff9800}.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:#e51c23}.has-error .form-control{border-color:#e51c23;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#b9151b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c}.has-error .input-group-addon{color:#e51c23;border-color:#e51c23;background-color:#f9bdbb}.has-error .form-control-feedback{color:#e51c23}.has-feedback label~.form-control-feedback{top:28px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#a6a6a6}@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{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:30px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:17px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 16px;font-size:13px;line-height:1.846;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.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:#444444;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#444444;background-color:#ffffff;border-color:transparent}.btn-default:focus,.btn-default.focus{color:#444444;background-color:#e6e6e6;border-color:rgba(0,0,0,0)}.btn-default:hover{color:#444444;background-color:#e6e6e6;border-color:rgba(0,0,0,0)}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#444444;background-color:#e6e6e6;border-color:rgba(0,0,0,0)}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#444444;background-color:#d4d4d4;border-color:rgba(0,0,0,0)}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.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{background-color:#ffffff;border-color:transparent}.btn-default .badge{color:#ffffff;background-color:#444444}.btn-primary{color:#ffffff;background-color:#2196f3;border-color:transparent}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#0c7cd5;border-color:rgba(0,0,0,0)}.btn-primary:hover{color:#ffffff;background-color:#0c7cd5;border-color:rgba(0,0,0,0)}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#0c7cd5;border-color:rgba(0,0,0,0)}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#0a68b4;border-color:rgba(0,0,0,0)}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.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{background-color:#2196f3;border-color:transparent}.btn-primary .badge{color:#2196f3;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#4caf50;border-color:transparent}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#3d8b40;border-color:rgba(0,0,0,0)}.btn-success:hover{color:#ffffff;background-color:#3d8b40;border-color:rgba(0,0,0,0)}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#3d8b40;border-color:rgba(0,0,0,0)}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#327334;border-color:rgba(0,0,0,0)}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.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{background-color:#4caf50;border-color:transparent}.btn-success .badge{color:#4caf50;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#9c27b0;border-color:transparent}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#771e86;border-color:rgba(0,0,0,0)}.btn-info:hover{color:#ffffff;background-color:#771e86;border-color:rgba(0,0,0,0)}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#771e86;border-color:rgba(0,0,0,0)}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#5d1769;border-color:rgba(0,0,0,0)}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.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{background-color:#9c27b0;border-color:transparent}.btn-info .badge{color:#9c27b0;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#ff9800;border-color:transparent}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#cc7a00;border-color:rgba(0,0,0,0)}.btn-warning:hover{color:#ffffff;background-color:#cc7a00;border-color:rgba(0,0,0,0)}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#cc7a00;border-color:rgba(0,0,0,0)}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#a86400;border-color:rgba(0,0,0,0)}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.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{background-color:#ff9800;border-color:transparent}.btn-warning .badge{color:#ff9800;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#e51c23;border-color:transparent}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#b9151b;border-color:rgba(0,0,0,0)}.btn-danger:hover{color:#ffffff;background-color:#b9151b;border-color:rgba(0,0,0,0)}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#b9151b;border-color:rgba(0,0,0,0)}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#991216;border-color:rgba(0,0,0,0)}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.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{background-color:#e51c23;border-color:transparent}.btn-danger .badge{color:#e51c23;background-color:#ffffff}.btn-link{color:#2196f3;font-weight:normal;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:#0a6ebd;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:#bbbbbb;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}.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 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.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;list-style:none;font-size:13px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.846;color:#666666;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#141414;background-color:#eeeeee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#2196f3}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#bbbbbb}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.846;color:#bbbbbb;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.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,.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-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-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:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,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:3px;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.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-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;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-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}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 16px;font-size:13px;font-weight:normal;line-height:1;color:#666666;text-align:center;background-color:transparent;border:1px solid transparent;border-radius:3px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:17px;border-radius:3px}.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-bottom-right-radius:0;border-top-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-bottom-left-radius:0;border-top-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{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left: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:#eeeeee}.nav>li.disabled>a{color:#bbbbbb}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#bbbbbb;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#2196f3}.nav .nav-divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid transparent}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.846;border:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee transparent}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#666666;background-color:transparent;border:1px solid transparent;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.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:3px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 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:#ffffff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:3px}.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:#ffffff;background-color:#2196f3}.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{text-align:center;margin-bottom:5px}.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:3px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:64px;margin-bottom:23px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:3px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.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}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right: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;padding:20.5px 15px;font-size:17px;line-height:23px;height:64px}.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;margin-right:15px;padding:9px 10px;margin-top:15px;margin-bottom:15px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px}.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:10.25px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:23px}@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:23px}.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:20.5px;padding-bottom:20.5px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-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);margin-top:13.5px;margin-bottom:13.5px}@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;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:3px;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:13.5px;margin-bottom:13.5px}.navbar-btn.btn-sm{margin-top:17px;margin-bottom:17px}.navbar-btn.btn-xs{margin-top:21px;margin-bottom:21px}.navbar-text{margin-top:20.5px;margin-bottom:20.5px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right: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:#ffffff;border-color:transparent}.navbar-default .navbar-brand{color:#666666}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#212121;background-color:transparent}.navbar-default .navbar-text{color:#bbbbbb}.navbar-default .navbar-nav>li>a{color:#666666}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#212121;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#212121;background-color:#eeeeee}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#eeeeee;color:#212121}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#666666}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#212121;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:#212121;background-color:#eeeeee}.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:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#666666}.navbar-default .navbar-link:hover{color:#212121}.navbar-default .btn-link{color:#666666}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#212121}.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:#cccccc}.navbar-inverse{background-color:#2196f3;border-color:transparent}.navbar-inverse .navbar-brand{color:#b2dbfb}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#bbbbbb}.navbar-inverse .navbar-nav>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#0c7cd5}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#0c84e4}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#0c7cd5;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;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:#ffffff;background-color:#0c7cd5}.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:#444444;background-color:transparent}}.navbar-inverse .navbar-link{color:#b2dbfb}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#b2dbfb}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.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:#444444}.breadcrumb{padding:8px 15px;margin-bottom:23px;list-style:none;background-color:#f5f5f5;border-radius:3px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#bbbbbb}.pagination{display:inline-block;padding-left:0;margin:23px 0;border-radius:3px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 16px;line-height:1.846;text-decoration:none;color:#2196f3;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#0a6ebd;background-color:#eeeeee;border-color:#dddddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#2196f3;border-color:#2196f3;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#bbbbbb;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:17px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:23px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.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:#bbbbbb;background-color:#ffffff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#bbbbbb}.label-default[href]:hover,.label-default[href]:focus{background-color:#a2a2a2}.label-primary{background-color:#2196f3}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#0c7cd5}.label-success{background-color:#4caf50}.label-success[href]:hover,.label-success[href]:focus{background-color:#3d8b40}.label-info{background-color:#9c27b0}.label-info[href]:hover,.label-info[href]:focus{background-color:#771e86}.label-warning{background-color:#ff9800}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#cc7a00}.label-danger{background-color:#e51c23}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#b9151b}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:normal;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#bbbbbb;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#2196f3;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#f9f9f9}.jumbotron h1,.jumbotron .h1{color:#444444}.jumbotron p{margin-bottom:15px;font-size:20px;font-weight:200}.jumbotron>hr{border-top-color:#e0e0e0}.container .jumbotron,.container-fluid .jumbotron{border-radius:3px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:59px}}.thumbnail{display:block;padding:4px;margin-bottom:23px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-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-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#2196f3}.thumbnail .caption{padding:9px;color:#666666}.alert{padding:15px;margin-bottom:23px;border:1px solid transparent;border-radius:3px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.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{background-color:#dff0d8;border-color:#d6e9c6;color:#4caf50}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#3d8b40}.alert-info{background-color:#e1bee7;border-color:#cba4dd;color:#9c27b0}.alert-info hr{border-top-color:#c191d6}.alert-info .alert-link{color:#771e86}.alert-warning{background-color:#ffe0b2;border-color:#ffc599;color:#ff9800}.alert-warning hr{border-top-color:#ffb67f}.alert-warning .alert-link{color:#cc7a00}.alert-danger{background-color:#f9bdbb;border-color:#f7a4af;color:#e51c23}.alert-danger hr{border-top-color:#f58c9a}.alert-danger .alert-link{color:#b9151b}@-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{overflow:hidden;height:23px;margin-bottom:23px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:23px;color:#ffffff;text-align:center;background-color:#2196f3;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;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:#4caf50}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#9c27b0}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#ff9800}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#e51c23}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.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{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}a.list-group-item,button.list-group-item{color:#555555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#bbbbbb;cursor:not-allowed}.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:#bbbbbb}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#2196f3;border-color:#2196f3}.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:#e3f2fd}.list-group-item-success{color:#4caf50;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#4caf50}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#4caf50;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#4caf50;border-color:#4caf50}.list-group-item-info{color:#9c27b0;background-color:#e1bee7}a.list-group-item-info,button.list-group-item-info{color:#9c27b0}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#9c27b0;background-color:#d8abe0}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#9c27b0;border-color:#9c27b0}.list-group-item-warning{color:#ff9800;background-color:#ffe0b2}a.list-group-item-warning,button.list-group-item-warning{color:#ff9800}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#ff9800;background-color:#ffd699}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#ff9800;border-color:#ff9800}.list-group-item-danger{color:#e51c23;background-color:#f9bdbb}a.list-group-item-danger,button.list-group-item-danger{color:#e51c23}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#e51c23;background-color:#f7a6a4}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#e51c23;border-color:#e51c23}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:23px;background-color:#ffffff;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:2px;border-top-left-radius:2px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:15px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.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-right-radius:2px;border-top-left-radius:2px}.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:2px;border-bottom-left-radius:2px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.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-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:2px;border-top-left-radius:2px}.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:2px;border-top-right-radius:2px}.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:2px}.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:2px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.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-left-radius:2px;border-bottom-right-radius:2px}.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:2px}.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:2px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #dddddd}.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{border:0;margin-bottom:0}.panel-group{margin-bottom:23px}.panel-group .panel{margin-bottom:0;border-radius:3px}.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 #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#212121;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#212121}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#2196f3}.panel-primary>.panel-heading{color:#ffffff;background-color:#2196f3;border-color:#2196f3}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#2196f3}.panel-primary>.panel-heading .badge{color:#2196f3;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#2196f3}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#ffffff;background-color:#4caf50;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#4caf50;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#cba4dd}.panel-info>.panel-heading{color:#ffffff;background-color:#9c27b0;border-color:#cba4dd}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#cba4dd}.panel-info>.panel-heading .badge{color:#9c27b0;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#cba4dd}.panel-warning{border-color:#ffc599}.panel-warning>.panel-heading{color:#ffffff;background-color:#ff9800;border-color:#ffc599}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ffc599}.panel-warning>.panel-heading .badge{color:#ff9800;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ffc599}.panel-danger{border-color:#f7a4af}.panel-danger>.panel-heading{color:#ffffff;background-color:#e51c23;border-color:#f7a4af}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#f7a4af}.panel-danger>.panel-heading .badge{color:#e51c23;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#f7a4af}.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;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f9f9f9;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:3px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:19.5px;font-weight:normal;line-height:1;color:#000000;text-shadow:none;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.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:#ffffff;border:1px solid #999999;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.846}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.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,0.5);box-shadow:0 5px 15px rgba(0,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:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.846;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#727272;border-radius:3px}.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:#727272}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#727272}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#727272}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.846;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;background-color:#ffffff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,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{margin:0;padding:8px 14px;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:2px 2px 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{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:rgba(0,0,0,0);border-top-color:rgba(0,0,0,0.075);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:rgba(0,0,0,0);border-right-color:rgba(0,0,0,0.075)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,0);border-bottom-color:rgba(0,0,0,0.075);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:rgba(0,0,0,0);border-left-color:rgba(0,0,0,0.075)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-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:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left: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;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;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;line-height:1;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%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,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:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right: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-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.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-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right: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}.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 !important}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 !important}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 !important}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 !important}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 !important}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}}.navbar{border:none;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.3);box-shadow:0 1px 2px rgba(0,0,0,0.3)}.navbar-brand{font-size:24px}.navbar-inverse .navbar-form input[type=text],.navbar-inverse .navbar-form input[type=password]{color:#fff;-webkit-box-shadow:inset 0 -1px 0 #b2dbfb;box-shadow:inset 0 -1px 0 #b2dbfb}.navbar-inverse .navbar-form input[type=text]::-moz-placeholder,.navbar-inverse .navbar-form input[type=password]::-moz-placeholder{color:#b2dbfb;opacity:1}.navbar-inverse .navbar-form input[type=text]:-ms-input-placeholder,.navbar-inverse .navbar-form input[type=password]:-ms-input-placeholder{color:#b2dbfb}.navbar-inverse .navbar-form input[type=text]::-webkit-input-placeholder,.navbar-inverse .navbar-form input[type=password]::-webkit-input-placeholder{color:#b2dbfb}.navbar-inverse .navbar-form input[type=text]:focus,.navbar-inverse .navbar-form input[type=password]:focus{-webkit-box-shadow:inset 0 -2px 0 #fff;box-shadow:inset 0 -2px 0 #fff}.btn-default{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-default:focus{background-color:#ffffff}.btn-default:hover,.btn-default:active:hover{background-color:#f0f0f0}.btn-default:active{background-color:#e0e0e0;background-image:-webkit-radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-image:-o-radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-image:radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-primary{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-primary:focus{background-color:#2196f3}.btn-primary:hover,.btn-primary:active:hover{background-color:#0d87e9}.btn-primary:active{background-color:#0b76cc;background-image:-webkit-radial-gradient(circle, #0b76cc 10%, #2196f3 11%);background-image:-o-radial-gradient(circle, #0b76cc 10%, #2196f3 11%);background-image:radial-gradient(circle, #0b76cc 10%, #2196f3 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-success{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-success:focus{background-color:#4caf50}.btn-success:hover,.btn-success:active:hover{background-color:#439a46}.btn-success:active{background-color:#39843c;background-image:-webkit-radial-gradient(circle, #39843c 10%, #4caf50 11%);background-image:-o-radial-gradient(circle, #39843c 10%, #4caf50 11%);background-image:radial-gradient(circle, #39843c 10%, #4caf50 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-info{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-info:focus{background-color:#9c27b0}.btn-info:hover,.btn-info:active:hover{background-color:#862197}.btn-info:active{background-color:#701c7e;background-image:-webkit-radial-gradient(circle, #701c7e 10%, #9c27b0 11%);background-image:-o-radial-gradient(circle, #701c7e 10%, #9c27b0 11%);background-image:radial-gradient(circle, #701c7e 10%, #9c27b0 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-warning{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-warning:focus{background-color:#ff9800}.btn-warning:hover,.btn-warning:active:hover{background-color:#e08600}.btn-warning:active{background-color:#c27400;background-image:-webkit-radial-gradient(circle, #c27400 10%, #ff9800 11%);background-image:-o-radial-gradient(circle, #c27400 10%, #ff9800 11%);background-image:radial-gradient(circle, #c27400 10%, #ff9800 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-danger{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-danger:focus{background-color:#e51c23}.btn-danger:hover,.btn-danger:active:hover{background-color:#cb171e}.btn-danger:active{background-color:#b0141a;background-image:-webkit-radial-gradient(circle, #b0141a 10%, #e51c23 11%);background-image:-o-radial-gradient(circle, #b0141a 10%, #e51c23 11%);background-image:radial-gradient(circle, #b0141a 10%, #e51c23 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn-link{-webkit-background-size:200% 200%;background-size:200% 200%;background-position:50%}.btn-link:focus{background-color:#ffffff}.btn-link:hover,.btn-link:active:hover{background-color:#f0f0f0}.btn-link:active{background-color:#e0e0e0;background-image:-webkit-radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-image:-o-radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-image:radial-gradient(circle, #e0e0e0 10%, #fff 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000% 1000%;-webkit-box-shadow:2px 2px 4px rgba(0,0,0,0.4);box-shadow:2px 2px 4px rgba(0,0,0,0.4)}.btn{text-transform:uppercase;border:none;-webkit-box-shadow:1px 1px 4px rgba(0,0,0,0.4);box-shadow:1px 1px 4px rgba(0,0,0,0.4);-webkit-transition:all 0.4s;-o-transition:all 0.4s;transition:all 0.4s}.btn-link{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;color:#444444}.btn-link:hover,.btn-link:focus{-webkit-box-shadow:none;box-shadow:none;color:#444444;text-decoration:none}.btn-default.disabled{background-color:rgba(0,0,0,0.1);color:rgba(0,0,0,0.4);opacity:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:0}.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:0}body{-webkit-font-smoothing:antialiased;letter-spacing:.1px}p{margin:0 0 1em}input,button{-webkit-font-smoothing:antialiased;letter-spacing:.1px}a{-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.table-hover>tbody>tr,.table-hover>tbody>tr>th,.table-hover>tbody>tr>td{-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}label{font-weight:normal}textarea,textarea.form-control,input.form-control,input[type=text],input[type=password],input[type=email],input[type=number],[type=text].form-control,[type=password].form-control,[type=email].form-control,[type=tel].form-control,[contenteditable].form-control{padding:0;border:none;border-radius:0;-webkit-appearance:none;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px}textarea:focus,textarea.form-control:focus,input.form-control:focus,input[type=text]:focus,input[type=password]:focus,input[type=email]:focus,input[type=number]:focus,[type=text].form-control:focus,[type=password].form-control:focus,[type=email].form-control:focus,[type=tel].form-control:focus,[contenteditable].form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3}textarea[disabled],textarea.form-control[disabled],input.form-control[disabled],input[type=text][disabled],input[type=password][disabled],input[type=email][disabled],input[type=number][disabled],[type=text].form-control[disabled],[type=password].form-control[disabled],[type=email].form-control[disabled],[type=tel].form-control[disabled],[contenteditable].form-control[disabled],textarea[readonly],textarea.form-control[readonly],input.form-control[readonly],input[type=text][readonly],input[type=password][readonly],input[type=email][readonly],input[type=number][readonly],[type=text].form-control[readonly],[type=password].form-control[readonly],[type=email].form-control[readonly],[type=tel].form-control[readonly],[contenteditable].form-control[readonly]{-webkit-box-shadow:none;box-shadow:none;border-bottom:1px dotted #ddd}textarea.input-sm,textarea.form-control.input-sm,input.form-control.input-sm,input[type=text].input-sm,input[type=password].input-sm,input[type=email].input-sm,input[type=number].input-sm,[type=text].form-control.input-sm,[type=password].form-control.input-sm,[type=email].form-control.input-sm,[type=tel].form-control.input-sm,[contenteditable].form-control.input-sm{font-size:12px}textarea.input-lg,textarea.form-control.input-lg,input.form-control.input-lg,input[type=text].input-lg,input[type=password].input-lg,input[type=email].input-lg,input[type=number].input-lg,[type=text].form-control.input-lg,[type=password].form-control.input-lg,[type=email].form-control.input-lg,[type=tel].form-control.input-lg,[contenteditable].form-control.input-lg{font-size:17px}select,select.form-control{border:0;border-radius:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding-left:0;padding-right:0\9;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=);-webkit-background-size:13px 13px;background-size:13px;background-repeat:no-repeat;background-position:right center;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px;line-height:1.5}select::-ms-expand,select.form-control::-ms-expand{display:none}select.input-sm,select.form-control.input-sm{font-size:12px}select.input-lg,select.form-control.input-lg{font-size:17px}select:focus,select.form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=)}select[multiple],select.form-control[multiple]{background:none}.radio label,.radio-inline label,.checkbox label,.checkbox-inline label{padding-left:25px}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="radio"],.checkbox-inline input[type="radio"],.radio input[type="checkbox"],.radio-inline input[type="checkbox"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{margin-left:-25px}input[type="radio"],.radio input[type="radio"],.radio-inline input[type="radio"]{position:relative;margin-top:6px;margin-right:4px;vertical-align:top;border:none;background-color:transparent;-webkit-appearance:none;appearance:none;cursor:pointer}input[type="radio"]:focus,.radio input[type="radio"]:focus,.radio-inline input[type="radio"]:focus{outline:none}input[type="radio"]:before,.radio input[type="radio"]:before,.radio-inline input[type="radio"]:before,input[type="radio"]:after,.radio input[type="radio"]:after,.radio-inline input[type="radio"]:after{content:"";display:block;width:18px;height:18px;border-radius:50%;-webkit-transition:240ms;-o-transition:240ms;transition:240ms}input[type="radio"]:before,.radio input[type="radio"]:before,.radio-inline input[type="radio"]:before{position:absolute;left:0;top:-3px;background-color:#2196f3;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0)}input[type="radio"]:after,.radio input[type="radio"]:after,.radio-inline input[type="radio"]:after{position:relative;top:-3px;border:2px solid #666666}input[type="radio"]:checked:before,.radio input[type="radio"]:checked:before,.radio-inline input[type="radio"]:checked:before{-webkit-transform:scale(.5);-ms-transform:scale(.5);-o-transform:scale(.5);transform:scale(.5)}input[type="radio"]:disabled:checked:before,.radio input[type="radio"]:disabled:checked:before,.radio-inline input[type="radio"]:disabled:checked:before{background-color:#bbbbbb}input[type="radio"]:checked:after,.radio input[type="radio"]:checked:after,.radio-inline input[type="radio"]:checked:after{border-color:#2196f3}input[type="radio"]:disabled:after,.radio input[type="radio"]:disabled:after,.radio-inline input[type="radio"]:disabled:after,input[type="radio"]:disabled:checked:after,.radio input[type="radio"]:disabled:checked:after,.radio-inline input[type="radio"]:disabled:checked:after{border-color:#bbbbbb}input[type="checkbox"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:relative;border:none;margin-bottom:-4px;-webkit-appearance:none;appearance:none;cursor:pointer}input[type="checkbox"]:focus,.checkbox input[type="checkbox"]:focus,.checkbox-inline input[type="checkbox"]:focus{outline:none}input[type="checkbox"]:focus:after,.checkbox input[type="checkbox"]:focus:after,.checkbox-inline input[type="checkbox"]:focus:after{border-color:#2196f3}input[type="checkbox"]:after,.checkbox input[type="checkbox"]:after,.checkbox-inline input[type="checkbox"]:after{content:"";display:block;width:18px;height:18px;margin-top:-2px;margin-right:5px;border:2px solid #666666;border-radius:2px;-webkit-transition:240ms;-o-transition:240ms;transition:240ms}input[type="checkbox"]:checked:before,.checkbox input[type="checkbox"]:checked:before,.checkbox-inline input[type="checkbox"]:checked:before{content:"";position:absolute;top:0;left:6px;display:table;width:6px;height:12px;border:2px solid #fff;border-top-width:0;border-left-width:0;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}input[type="checkbox"]:checked:after,.checkbox input[type="checkbox"]:checked:after,.checkbox-inline input[type="checkbox"]:checked:after{background-color:#2196f3;border-color:#2196f3}input[type="checkbox"]:disabled:after,.checkbox input[type="checkbox"]:disabled:after,.checkbox-inline input[type="checkbox"]:disabled:after{border-color:#bbbbbb}input[type="checkbox"]:disabled:checked:after,.checkbox input[type="checkbox"]:disabled:checked:after,.checkbox-inline input[type="checkbox"]:disabled:checked:after{background-color:#bbbbbb;border-color:transparent}.has-warning input:not([type=checkbox]),.has-warning .form-control,.has-warning input.form-control[readonly],.has-warning input[type=text][readonly],.has-warning [type=text].form-control[readonly],.has-warning input:not([type=checkbox]):focus,.has-warning .form-control:focus{border-bottom:none;-webkit-box-shadow:inset 0 -2px 0 #ff9800;box-shadow:inset 0 -2px 0 #ff9800}.has-error input:not([type=checkbox]),.has-error .form-control,.has-error input.form-control[readonly],.has-error input[type=text][readonly],.has-error [type=text].form-control[readonly],.has-error input:not([type=checkbox]):focus,.has-error .form-control:focus{border-bottom:none;-webkit-box-shadow:inset 0 -2px 0 #e51c23;box-shadow:inset 0 -2px 0 #e51c23}.has-success input:not([type=checkbox]),.has-success .form-control,.has-success input.form-control[readonly],.has-success input[type=text][readonly],.has-success [type=text].form-control[readonly],.has-success input:not([type=checkbox]):focus,.has-success .form-control:focus{border-bottom:none;-webkit-box-shadow:inset 0 -2px 0 #4caf50;box-shadow:inset 0 -2px 0 #4caf50}.has-warning .input-group-addon,.has-error .input-group-addon,.has-success .input-group-addon{color:#666666;border-color:transparent;background-color:transparent}.form-group-lg select,.form-group-lg select.form-control{line-height:1.5}.nav-tabs>li>a,.nav-tabs>li>a:focus{margin-right:0;background-color:transparent;border:none;color:#666666;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus:hover{background-color:transparent;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus{border:none;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus:hover{border:none;color:#2196f3}.nav-tabs>li.disabled>a{-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd}.nav-tabs.nav-justified>li>a,.nav-tabs.nav-justified>li>a:hover,.nav-tabs.nav-justified>li>a:focus,.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:none}.nav-tabs .dropdown-menu{margin-top:0}.dropdown-menu{margin-top:0;border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.alert{border:none;color:#fff}.alert-success{background-color:#4caf50}.alert-info{background-color:#9c27b0}.alert-warning{background-color:#ff9800}.alert-danger{background-color:#e51c23}.alert a:not(.close):not(.btn),.alert .alert-link{color:#fff;font-weight:bold}.alert .close{color:#fff}.badge{padding:4px 6px 4px}.progress{position:relative;z-index:1;height:6px;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress-bar:last-child{border-radius:0 3px 3px 0}.progress-bar:last-child:before{display:block;content:"";position:absolute;width:100%;height:100%;left:0;right:0;z-index:-1;background-color:#cae6fc}.progress-bar-success:last-child.progress-bar:before{background-color:#c7e7c8}.progress-bar-info:last-child.progress-bar:before{background-color:#edc9f3}.progress-bar-warning:last-child.progress-bar:before{background-color:#ffe0b3}.progress-bar-danger:last-child.progress-bar:before{background-color:#f28e92}.close{font-size:34px;font-weight:300;line-height:24px;opacity:0.6;-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.close:hover{opacity:1}.list-group-item{padding:15px}.list-group-item-text{color:#bbbbbb}.well{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.panel{border:none;border-radius:2px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.panel-heading{border-bottom:none}.panel-footer{border-top:none}.popover{border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.carousel-caption h1,.carousel-caption h2,.carousel-caption h3,.carousel-caption h4,.carousel-caption h5,.carousel-caption h6{color:inherit}
General Comments 0
You need to be logged in to leave comments. Login now