##// END OF EJS Templates
Primer commit radarsys_met
amorales -
r345:695a10341b92
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,6
1 from django.contrib import admin
2 from .models import USRPConfiguration
3
4 # Register your models here.
5
6 admin.site.register(USRPConfiguration)
@@ -0,0 +1,28
1 [{"fields": {"number_of_codes": 0, "codes": "[]", "name": "None", "bits_per_code": 0}, "model": "rc.rclinecode", "pk": 1},
2 {"fields": {"number_of_codes": 2, "codes": "[u'11101101', u'11100010']", "name": "COMPLEMENTARY_CODE_8", "bits_per_code": 8}, "model": "rc.rclinecode", "pk": 2},
3 {"fields": {"number_of_codes": 1, "codes": "[u'1101101001000100010001111000']", "name": "BINARY_CODE_28", "bits_per_code": 28}, "model": "rc.rclinecode", "pk": 3},
4 {"fields": {"number_of_codes": 2, "codes": "[u'11', u'10']", "name": "COMPLEMENTARY_CODE_2", "bits_per_code": 2}, "model": "rc.rclinecode", "pk": 4},
5 {"fields": {"number_of_codes": 2, "codes": "[u'1110110111100010111011010001110111101101111000100001001011100010', u'1110110111100010111011010001110100010010000111011110110100011101']", "name": "COMPLEMENTARY_CODE_64", "bits_per_code": 64}, "model": "rc.rclinecode", "pk": 5},
6 {"fields": {"number_of_codes": 1, "codes": "[u'11100010010']", "name": "BARKER11", "bits_per_code": 11}, "model": "rc.rclinecode", "pk": 6},
7 {"fields": {"number_of_codes": 2, "codes": "[u'1111100110101' ]", "name": "BARKER13", "bits_per_code": 13}, "model": "rc.rclinecode", "pk": 7},
8 {"fields": {"number_of_codes": 2, "codes": "[u'1101101001000100010001111000', u'0010010110111011101110000111']", "name": "BINARY_CODE_28_FLIP", "bits_per_code": 28}, "model": "rc.rclinecode", "pk": 8},
9 {"fields": {"number_of_codes": 2, "codes": "[u'11101101111000101110110100011101', u'11101101111000100001001011100010']", "name": "COMPLEMENTARY_CODE_32", "bits_per_code": 32}, "model": "rc.rclinecode", "pk": 9},
10 {"fields": {"number_of_codes": 128, "codes": "[u'1111000100100101', u'1011001010010111', u'1101001000100000', u'1001000110010010', u'1110001001111011', u'1010000111001001', u'1100000101111110', u'1000001011001100', u'1111101001010110', u'1011100111100100', u'1101100101010011', u'1001101011100001', u'1110100100001000', u'1010101010111010', u'1100101000001101', u'1000100110111111', u'1111010010011100', u'1011011100101110', u'1101011110011001', u'1001010000101011', u'1110011111000010', u'1010010001110000', u'1100010011000111', u'1000011101110101', u'1111111111101111', u'1011110001011101', u'1101110011101010', u'1001111101011000', u'1110110010110001', u'1010111100000011', u'1100111110110100', u'1000110000000110', u'0011111000000011', u'0111110110110001', u'0001110100000110', u'0101111010110100', u'0010110101011101', u'0110111011101111', u'0000111001011000', u'0100110111101010', u'0011010101110000', u'0111011011000010', u'0001011001110101', u'0101010111000111', u'0010011000101110', u'0110010110011100', u'0000010100101011', u'0100011010011001', u'0011101110111010', u'0111100000001000', u'0001100010111111', u'0101101100001101', u'0010100011100100', u'0110101101010110', u'0000101111100001', u'0100100001010011', u'0011000011001001', u'0111001101111011', u'0001001111001100', u'0101000001111110', u'0010001110010111', u'0110000000100101', u'0000000010010010', u'0100001100100000', u'1010110011001110', u'1110111101111100', u'1000111111001011', u'1100110001111001', u'1011111110010000', u'1111110000100010', u'1001110010010101', u'1101111100100111', u'1010011110111101', u'1110010000001111', u'1000010010111000', u'1100011100001010', u'1011010011100011', u'1111011101010001', u'1001011111100110', u'1101010001010100', u'1010100101110111', u'1110101011000101', u'1000101001110010', u'1100100111000000', u'1011101000101001', u'1111100110011011', u'1001100100101100', u'1101101010011110', u'1010001000000100', u'1110000110110110', u'1000000100000001', u'1100001010110011', u'1011000101011010', u'1111001011101000', u'1001001001011111', u'1101000111101101', u'1100100111000110', u'1000101001110100', u'1110101011000011', u'1010100101110001', u'1101101010011000', u'1001100100101010', u'1111100110011101', u'1011101000101111', u'1100001010110101', u'1000000100000111', u'1110000110110000', u'1010001000000010', u'1101000111101011', u'1001001001011001', u'1111001011101110', u'1011000101011100', u'1100110001111111', u'1000111111001101', u'1110111101111010', u'1010110011001000', u'1101111100100001', u'1001110010010011', u'1111110000100100', u'1011111110010110', u'1100011100001100', u'1000010010111110', u'1110010000001001', u'1010011110111011', u'1101010001010010', u'1001011111100000', u'1111011101010111', u'1011010011100101']", "name": "AC128", "bits_per_code": 16}, "model": "rc.rclinecode", "pk": 10},
11 {"fields": {"number_of_codes": 2, "codes": "[u'11101101111000101110110100011101111011011110001000010010111000101110110111100010111011010001110100010010000111011110110100011101', u'11101101111000101110110100011101111011011110001000010010111000100001001000011101000100101110001011101101111000100001001011100010']", "name": "COMPLEMENTARY_CODE_128", "bits_per_code": 128}, "model": "rc.rclinecode", "pk": 11},
12 {"fields": {"number_of_codes": 2, "codes": "[u'1110110111100010', u'1110110100011101']", "name": "COMPLEMENTARY_CODE_16", "bits_per_code": 16}, "model": "rc.rclinecode", "pk": 12},
13 {"fields": {"number_of_codes": 1, "codes": "[u'11']", "name": "BARKER2", "bits_per_code": 2}, "model": "rc.rclinecode", "pk": 13},
14 {"fields": {"number_of_codes": 1, "codes": "[u'110']", "name": "BARKER3", "bits_per_code": 3}, "model": "rc.rclinecode", "pk": 14},
15 {"fields": {"number_of_codes": 2, "codes": "[u'1110', u'1101']", "name": "COMPLEMENTARY_CODE_4", "bits_per_code": 4}, "model": "rc.rclinecode", "pk": 15},
16 {"fields": {"number_of_codes": 1, "codes": "[u'1110010']", "name": "BARKER7", "bits_per_code": 7}, "model": "rc.rclinecode", "pk": 16},
17 {"fields": {"number_of_codes": 1, "codes": "[u'1101']", "name": "BARKER4", "bits_per_code": 4}, "model": "rc.rclinecode", "pk": 17},
18 {"fields": {"number_of_codes": 1, "codes": "[u'11101']", "name": "BARKER5", "bits_per_code": 5}, "model": "rc.rclinecode", "pk": 18},
19 {"fields": {"number_of_codes": 0, "codes": "[]", "name": "USERDEFINE", "bits_per_code": 0}, "model": "rc.rclinecode", "pk": 19},
20 {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"range\": { \"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tr", "description": ""}, "model": "rc.rclinetype", "pk": 1},
21 {"fields": {"params": "{\"pulse_width\":{\"value\": 0, \"widget\":\"dc\"},\r\n \"delays\":{\"value\": \"\", \"widget\":\"km\", \"help\": \"Delay entries separated by commas (TAUs)\"},\r\n \"range\":{\"value\": 0, \"help\": \"Frame numbers or frame ranges separated by commas, use 0 for all frames eg: 1,2,10-15\"}}", "name": "tx", "description": ""}, "model": "rc.rclinetype", "pk": 2},
22 {"fields": {"params": "{\"TX_ref\": {\"model\": \"RCLine\", \"value\": \"\"}, \"code\": {\"model\":\"RCLineCode\",\"value\": \"\"}, \"codes\":{\"value\":\"\", \"widget\":\"codes\"}}", "name": "codes", "description": ""}, "model": "rc.rclinetype", "pk": 3},
23 {"fields": {"params": "{ \"TX_ref\":{\"model\": \"RCLine\", \"value\": \"\"}, \"params\": {\"first_height\":{ \"value\": 0, \"widget\":\"km\"},\"resolution\": {\"value\": 0, \"widget\":\"km\"}, \"number_of_samples\": { \"value\": 0, \"help\":\"number of samples (NSA)\"}, \"last_height\": { \"value\": 0}}}", "name": "windows", "description": ""}, "model": "rc.rclinetype", "pk": 4},
24 {"fields": {"params": "{\"invert\":{\"value\": 0, \"help\": \"Set to 1 for synchro pulse at the end\"}}", "name": "sync", "description": ""}, "model": "rc.rclinetype", "pk": 5},
25 {"fields": {"params": "{ \"periodic\": { \"value\": 0, \"help\": \"Set to 1 for IPP periodic\"}, \"params\": {\"begin\": { \"value\": 0, \"widget\":\"unit\"}, \"end\": {\"value\": 0, \"widget\":\"unit\"}}}", "name": "prog_pulses", "description": ""}, "model": "rc.rclinetype", "pk": 6},
26 {"fields": {"params": "{\"number_of_flips\": {\"value\": 0}}", "name": "flip", "description": ""}, "model": "rc.rclinetype", "pk": 7},
27 {"fields": {"params": "{}", "name": "none", "description": ""}, "model": "rc.rclinetype", "pk": 8},
28 {"fields": {"params": "{}", "name": "mix", "description": ""}, "model": "rc.rclinetype", "pk": 9}] No newline at end of file
@@ -0,0 +1,57
1 import os
2 import json
3
4 from django import forms
5 from django.utils.safestring import mark_safe
6 from apps.main.models import Device
7 from apps.main.forms import add_empty_choice
8 from .models import USRPConfiguration
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10
11 def create_choices_from_model(model, conf_id, all_choice=False):
12
13 instance = globals()[model]
14 choices = instance.objects.all().values_list('pk', 'name')
15
16 return choices
17
18
19 class USRPConfigurationForm(forms.ModelForm):
20
21 def __init__(self, *args, **kwargs):
22 super(USRPConfigurationForm, self).__init__(*args, **kwargs)
23
24 instance = getattr(self, 'instance', None)
25
26 if instance and instance.pk:
27
28 devices = Device.objects.filter(device_type__name='usrp_rx')
29 if instance.experiment:
30 self.fields['experiment'].widget.attrs['read_only'] = True
31 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
32 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
33
34 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
35 self.fields['experiment'].widget.attrs['readonly'] = True
36
37 class Meta:
38 model = USRPConfiguration
39 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
40
41 def clean(self):
42 form_data = super(USRPConfigurationForm, self).clean()
43
44 if 'clock_divider' in form_data:
45 if form_data['clock_divider']<1:
46 self.add_error('clock_divider', 'Invalid Value')
47 #else:
48 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
49 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
50
51 return form_data
52
53 def save(self, *args, **kwargs):
54 conf = super(USRPConfigurationForm, self).save(*args, **kwargs)
55 conf.save()
56 return conf
57
This diff has been collapsed as it changes many lines, (710 lines changed) Show them Hide them
@@ -0,0 +1,710
1
2
3 import ast
4 import json
5 import requests
6 import numpy as np
7 import base64
8 from struct import pack
9
10 from django.db import models
11 from django.urls import reverse
12 from django.core.validators import MinValueValidator, MaxValueValidator
13
14 from apps.main.models import Configuration
15 from apps.main.utils import Params
16 from devices.rc import api
17
18 BOARD_VALUE = (
19 ('1', 'A:AB'),
20 ('2', 'AB')
21 )
22
23 ANT_VALUE = (
24 ('1', 'Rx'),
25 ('2', 'Tx')
26 )
27
28 CLK_VALUE = (
29 ('1', 'internal'),
30 ('2', 'external')
31 )
32
33 TIME_VALUE = (
34 ('1', 'internal'),
35 ('2', 'external')
36 )
37
38 LINE_TYPES = (
39 ('none', 'Not used'),
40 ('tr', 'Transmission/reception selector signal'),
41 ('tx', 'A modulating signal (Transmission pulse)'),
42 ('codes', 'BPSK modulating signal'),
43 ('windows', 'Sample window signal'),
44 ('sync', 'Synchronizing signal'),
45 ('flip', 'IPP related periodic signal'),
46 ('prog_pulses', 'Programmable pulse'),
47 ('mix', 'Mixed line'),
48 )
49
50
51 SAMPLING_REFS = (
52 ('none', 'No Reference'),
53 ('begin_baud', 'Begin of the first baud'),
54 ('first_baud', 'Middle of the first baud'),
55 ('sub_baud', 'Middle of the sub-baud')
56 )
57
58 DAT_CMDS = {
59 # Pulse Design commands
60 'DISABLE' : 0, # Disables pulse generation
61 'ENABLE' : 24, # Enables pulse generation
62 'DELAY_START' : 40, # Write delay status to memory
63 'FLIP_START' : 48, # Write flip status to memory
64 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
65 'TX_ONE' : 72, # Output '0' in line TX
66 'TX_ZERO' : 88, # Output '0' in line TX
67 'SW_ONE' : 104, # Output '0' in line SW
68 'SW_ZERO' : 112, # Output '1' in line SW
69 'RESTART': 120, # Restarts CR8 Firmware
70 'CONTINUE' : 253, # Function Unknown
71 # Commands available to new controllers
72 # 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.
73 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
74 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
75 'CLOCK_DIVIDER' : 8,
76 }
77
78 MAX_BITS = 8
79
80 # Rotate left: 0b1001 --> 0b0011
81 rol = lambda val, r_bits: \
82 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
83 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
84
85 # Rotate right: 0b1001 --> 0b1100
86 ror = lambda val, r_bits: \
87 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
88 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
89
90
91 class USRPConfiguration(Configuration):
92
93 daughterboard = models.CharField(
94 verbose_name='Daughterboard',
95 max_length=3,
96 choices=BOARD_VALUE,
97 null=False,
98 blank=False
99 )
100
101 antenna = models.CharField(
102 verbose_name='Antenna',
103 max_length=3,
104 choices=ANT_VALUE,
105 null=False,
106 blank=False
107 )
108
109 samplerate = models.FloatField(
110 verbose_name='Sample Rate',
111 blank=False,
112 null=False
113 )
114
115 frequency = models.FloatField(
116 verbose_name='Frequency',
117 blank=False,
118 null=False
119 )
120
121 datadir = models.CharField(
122 verbose_name="Data Directory",
123 max_length=100,
124 default='',
125 blank=False,
126 null=False
127 )
128
129 clocksource = models.CharField(
130 verbose_name='Clock Source',
131 max_length=3,
132 choices=CLK_VALUE,
133 null=False,
134 blank=False
135 )
136
137 timesource = models.CharField(
138 verbose_name='Time Source',
139 max_length=3,
140 choices=TIME_VALUE,
141 null=False,
142 blank=False
143 )
144
145 clockrate = models.FloatField(
146 verbose_name='Clock Rate',
147 blank=False,
148 null=False
149 )
150
151
152 class Meta:
153 db_table = 'usrp_configurations'
154
155 def __str__(self):
156 return self.label
157
158 def get_absolute_url_plot(self):
159 return reverse('url_plot_usrp_rx_pulses', args=[str(self.id)])
160
161 @property
162 def ipp_unit(self):
163
164 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
165
166 def clone(self, **kwargs):
167
168 lines = self.get_lines()
169 self.pk = None
170 self.id = None
171 for attr, value in kwargs.items():
172 setattr(self, attr, value)
173 self.save()
174
175 for line in lines:
176 line.clone(rc_configuration=self)
177
178 new_lines = self.get_lines()
179 for line in new_lines:
180 line_params = json.loads(line.params)
181 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
182 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
183 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
184 line.params = json.dumps(line_params)
185 line.save()
186
187 return self
188
189 def get_lines(self, **kwargs):
190 '''
191 Retrieve configuration lines
192 '''
193
194 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
195
196
197 def clean_lines(self):
198 '''
199 '''
200
201 empty_line = RCLineType.objects.get(name='none')
202
203 for line in self.get_lines():
204 line.line_type = empty_line
205 line.params = '{}'
206 line.save()
207
208 def dict_to_parms(self, params, id=None):
209 '''
210 '''
211
212 if id:
213 data = Params(params).get_conf(id_conf=id)
214 else:
215 data = Params(params).get_conf(dtype='usrp')
216
217 #print(data)
218 # self.name = data['name']
219 self.ipp = data['ipp']
220 self.ntx = data['ntx']
221 self.clock_in = data['clock_in']
222 self.clock_divider = data['clock_divider']
223 self.clock = data['clock']
224 self.time_before = data['time_before']
225 self.time_after = data['time_after']
226 self.sync = data['sync']
227 self.sampling_reference = data['sampling_reference']
228 self.total_units = self.ipp*self.ntx*self.km2unit
229 self.save()
230 self.clean_lines()
231
232 #print(params)
233
234 positions = {'tx':0, 'tr':0}
235 for i, id in enumerate(data['lines']):
236 line_data = params['lines']['byId'][id]
237 line_type = RCLineType.objects.get(name=line_data['line_type'])
238 if line_type.name == 'codes':
239 code = RCLineCode.objects.get(name=line_data['params']['code'])
240 line_data['params']['code'] = code.pk
241 if line_type.name == 'tx':
242 position = positions['tx']
243 positions['tx'] += 1
244 elif line_type.name == 'tr':
245 position = positions['tr']
246 positions['tr'] += 1
247 else:
248 position = 0
249 line, dum = RCLine.objects.update_or_create(
250 rc_configuration=self,
251 channel=i,
252 position=position,
253 defaults={
254 'line_type': line_type,
255 'params': json.dumps(line_data['params'])
256 }
257 )
258
259 for i, line in enumerate(self.get_lines()):
260 line_params = json.loads(line.params)
261 if 'TX_ref' in line_params:
262 if line_params['TX_ref'] in (0, '0'):
263 line_params['TX_ref'] = '0'
264 else:
265 ref_id = '{}'.format(line_params['TX_ref'])
266 ref_line = params['lines']['byId'][ref_id]
267 line_params['TX_ref'] = RCLine.objects.get(
268 rc_configuration=self,
269 params=json.dumps(ref_line['params'])
270 ).pk
271 line.params = json.dumps(line_params)
272 print(line.params)
273 line.save()
274 print("Fin de dict to param")
275
276 def get_delays(self):
277
278 pulses = [line.pulses_as_points() for line in self.get_lines()]
279 points = [tup for tups in pulses for tup in tups]
280 points = set([x for tup in points for x in tup])
281 points = list(points)
282 points.sort()
283
284 if points[0]!=0:
285 points.insert(0, 0)
286
287 return [points[i+1]-points[i] for i in range(len(points)-1)]
288
289
290 def get_pulses(self, binary=True):
291
292 pulses = [line.pulses_as_points() for line in self.get_lines()]
293 tuples = [tup for tups in pulses for tup in tups]
294 points = set([x for tup in tuples for x in tup])
295 points = list(points)
296 points.sort()
297 states = []
298 last = [0 for x in pulses]
299
300 for x in points:
301 dum = []
302 for i, tups in enumerate(pulses):
303 ups = [tup[0] for tup in tups if tup!=(0,0)]
304 dws = [tup[1] for tup in tups if tup!=(0,0)]
305 if x in ups:
306 dum.append(1)
307 elif x in dws:
308 dum.append(0)
309 else:
310 dum.append(last[i])
311 states.append(dum)
312 last = dum
313
314 if binary:
315 ret = []
316 for flips in states:
317 flips.reverse()
318 ret.append(int(''.join([str(x) for x in flips]), 2))
319 states = ret
320
321 return states[:-1]
322
323 def add_cmd(self, cmd):
324
325 if cmd in DAT_CMDS:
326 return (255, DAT_CMDS[cmd])
327
328 def add_data(self, value):
329
330 return (254, value-1)
331
332 def parms_to_binary(self, dat=True):
333 '''
334 Create "dat" stream to be send to CR
335 '''
336
337 data = bytearray()
338 # create header
339 data.extend(self.add_cmd('DISABLE'))
340 data.extend(self.add_cmd('CONTINUE'))
341 data.extend(self.add_cmd('RESTART'))
342
343 if self.control_sw:
344 data.extend(self.add_cmd('SW_ONE'))
345 else:
346 data.extend(self.add_cmd('SW_ZERO'))
347
348 if self.control_tx:
349 data.extend(self.add_cmd('TX_ONE'))
350 else:
351 data.extend(self.add_cmd('TX_ZERO'))
352
353 # write divider
354 data.extend(self.add_cmd('CLOCK_DIVIDER'))
355 data.extend(self.add_data(self.clock_divider))
356
357 # write delays
358 data.extend(self.add_cmd('DELAY_START'))
359 # first delay is always zero
360 data.extend(self.add_data(1))
361
362 delays = self.get_delays()
363
364 for delay in delays:
365 while delay>252:
366 data.extend(self.add_data(253))
367 delay -= 253
368 data.extend(self.add_data(int(delay)))
369
370 # write flips
371 data.extend(self.add_cmd('FLIP_START'))
372
373 states = self.get_pulses(binary=True)
374
375
376 last = 0
377 for flip, delay in zip(states, delays):
378 data.extend(self.add_data((flip^last)+1))
379 last = flip
380 while delay>252:
381 data.extend(self.add_data(1))
382 delay -= 253
383
384 # write sampling period
385 data.extend(self.add_cmd('SAMPLING_PERIOD'))
386 wins = self.get_lines(line_type__name='windows')
387 if wins:
388 win_params = json.loads(wins[0].params)['params']
389 if win_params:
390 dh = int(win_params[0]['resolution']*self.km2unit)
391 else:
392 dh = 1
393 else:
394 dh = 1
395 data.extend(self.add_data(dh))
396
397 # write enable
398 data.extend(self.add_cmd('ENABLE'))
399
400 if not dat:
401 return data
402
403 return '\n'.join(['{}'.format(x) for x in data])
404
405 def update_pulses(self):
406 contador = 0
407 for line in self.get_lines():
408 contador=contador+1
409 print(contador)
410 line.update_pulses()
411
412 def plot_pulses2(self, km=False):
413
414 import matplotlib
415 matplotlib.use('Agg')
416 import matplotlib.pyplot as plt
417 from bokeh.resources import CDN
418 from bokeh.embed import components
419 from bokeh.mpl import to_bokeh
420 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
421
422 lines = self.get_lines()
423
424 N = len(lines)
425 npoints = self.total_units/self.km2unit if km else self.total_units
426 fig = plt.figure(figsize=(12, 2+N*0.5))
427 ax = fig.add_subplot(111)
428 labels = ['IPP']
429
430 for i, line in enumerate(lines):
431 labels.append(line.get_name(channel=True))
432 l = ax.plot((0, npoints),(N-i-1, N-i-1))
433 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
434 ax.broken_barh(points, (N-i-1, 0.5),
435 edgecolor=l[0].get_color(), facecolor='none')
436
437 n = 0
438 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
439 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
440 if n%f==0:
441 ax.text(x, N, '%s' % n, size=10)
442 n += 1
443
444 labels.reverse()
445 ax.set_yticks(range(len(labels)))
446 ax.set_yticklabels(labels)
447 ax.set_xlabel = 'Units'
448 plot = to_bokeh(fig, use_pandas=False)
449 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
450 plot.toolbar_location="above"
451
452 return components(plot, CDN)
453
454 def plot_pulses(self, km=False):
455
456 from bokeh.plotting import figure
457 from bokeh.resources import CDN
458 from bokeh.embed import components
459 from bokeh.models import FixedTicker, PrintfTickFormatter
460 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
461 from bokeh.models.sources import ColumnDataSource
462
463 lines = self.get_lines().reverse()
464
465 N = len(lines)
466 npoints = self.total_units/self.km2unit if km else self.total_units
467 ipp = self.ipp if km else self.ipp*self.km2unit
468
469 hover = HoverTool(tooltips=[("Line", "@name"),
470 ("IPP", "@ipp"),
471 ("X", "@left")])
472
473 tools = [PanTool(dimensions="width"),
474 WheelZoomTool(dimensions="width"),
475 hover, SaveTool()]
476
477 plot = figure(width=1000,
478 height=40+N*50,
479 y_range = (0, N),
480 tools=tools,
481 toolbar_location='above',
482 toolbar_sticky=False,)
483
484 plot.xaxis.axis_label = 'Km' if km else 'Units'
485 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
486 plot.yaxis.axis_label = 'Pulses'
487 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
488 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
489
490 for i, line in enumerate(lines):
491
492 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
493
494 source = ColumnDataSource(data = dict(
495 bottom = [i for tup in points],
496 top = [i+0.5 for tup in points],
497 left = [tup[0] for tup in points],
498 right = [tup[1] for tup in points],
499 ipp = [int(tup[0]/ipp) for tup in points],
500 name = [line.get_name() for tup in points]
501 ))
502
503 plot.quad(
504 bottom = 'bottom',
505 top = 'top',
506 left = 'left',
507 right = 'right',
508 source = source,
509 fill_alpha = 0,
510 #line_color = 'blue',
511 )
512
513 plot.line([0, npoints], [i, i])#, color='blue')
514
515 return components(plot, CDN)
516
517 def request(self, cmd, method='get', **kwargs):
518
519 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
520 payload = req.json()
521 return payload
522
523 def status_device(self):
524
525 try:
526 self.device.status = 0
527 payload = self.request('status')
528 if payload['status']=='enable':
529 self.device.status = 3
530 elif payload['status']=='disable':
531 self.device.status = 2
532 else:
533 self.device.status = 1
534 self.device.save()
535 self.message = 'RC status: {}'.format(payload['status'])
536 return False
537 except Exception as e:
538 if 'No route to host' not in str(e):
539 self.device.status = 4
540 self.device.save()
541 self.message = 'RC status: {}'.format(str(e))
542 return False
543
544 self.device.save()
545 return True
546
547 def reset_device(self):
548
549 try:
550 payload = self.request('reset', 'post')
551 if payload['reset']=='ok':
552 self.message = 'RC restarted OK'
553 self.device.status = 2
554 self.device.save()
555 else:
556 self.message = 'RC restart fail'
557 self.device.status = 4
558 self.device.save()
559 except Exception as e:
560 self.message = 'RC reset: {}'.format(str(e))
561 return False
562
563 return True
564
565 def stop_device(self):
566
567 try:
568 payload = self.request('stop', 'post')
569 self.message = 'RC stop: {}'.format(payload['stop'])
570 if payload['stop']=='ok':
571 self.device.status = 2
572 self.device.save()
573 else:
574 self.device.status = 4
575 self.device.save()
576 return False
577 except Exception as e:
578 if 'No route to host' not in str(e):
579 self.device.status = 4
580 else:
581 self.device.status = 0
582 self.message = 'RC stop: {}'.format(str(e))
583 self.device.save()
584 return False
585
586 return True
587
588 def start_device(self):
589 print("Entró al start")
590 try:
591 usrp = USRPConfiguration.objects.get(pk=self)
592 usrp_daughterboard = usrp.get_daughterboard_display()
593 usrp_antenna = usrp.get_antenna_display()
594 usrp_clocksource = usrp.get_clocksource_display()
595 usrp_timesource = usrp.get_timesource_display()
596 print(usrp)
597 payload = {'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna, 'sample_rate': usrp.samplerate, 'frequency': usrp.frequency,
598 'datadir': usrp.datadir, 'clock_source': usrp_clocksource, 'time_source': usrp_timesource, 'clock_rate':usrp.clockrate}
599 print(payload)
600 x = requests.post(self.device.url("usrp"), json=payload)
601 print(x)
602 #payload = self.request('usrp', 'post', data=json.dumps(data))
603 #print(payload)
604 self.message = 'RC start: {}'.format(payload['start'])
605 if payload['start']=='ok':
606 self.device.status = 3
607 self.device.save()
608 else:
609 return False
610 except Exception as e:
611 if 'No route to host' not in str(e):
612 self.device.status = 4
613 else:
614 self.device.status = 0
615 self.message = 'RC start: {}'.format(str(e))
616 self.device.save()
617 return False
618
619 return True
620
621 def write_device(self, raw=False):
622
623 if not raw:
624 clock = RCClock.objects.get(rc_configuration=self)
625 print(clock)
626 if clock.mode:
627 data = {'default': clock.frequency}
628 else:
629 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
630 payload = self.request('setfreq', 'post', data=json.dumps(data))
631 print(payload)
632 if payload['command'] != 'ok':
633 self.message = 'RC write: {}'.format(payload['command'])
634 else:
635 self.message = payload['programming']
636 if payload['programming'] == 'fail':
637 self.message = 'RC write: error programming CGS chip'
638
639 values = []
640 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
641 while delay>65536:
642 values.append((pulse, 65535))
643 delay -= 65536
644 values.append((pulse, delay-1))
645 data = bytearray()
646 #reset
647 data.extend((128, 0))
648 #disable
649 data.extend((129, 0))
650 #SW switch
651 if self.control_sw:
652 data.extend((130, 2))
653 else:
654 data.extend((130, 0))
655 #divider
656 data.extend((131, self.clock_divider-1))
657 #enable writing
658 data.extend((139, 62))
659
660 last = 0
661 for tup in values:
662 vals = pack('<HH', last^tup[0], tup[1])
663 last = tup[0]
664 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
665
666 #enable
667 data.extend((129, 1))
668
669 if raw:
670 return b64encode(data)
671
672 try:
673 payload = self.request('stop', 'post')
674 payload = self.request('reset', 'post')
675 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
676 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
677 n = len(data)
678 x = 0
679 #while x < n:
680 payload = self.request('write', 'post', data=b64encode(data))
681 # x += 1024
682
683 if payload['write']=='ok':
684 self.device.status = 3
685 self.device.save()
686 self.message = 'RC configured and started'
687 else:
688 self.device.status = 1
689 self.device.save()
690 self.message = 'RC write: {}'.format(payload['write'])
691 return False
692
693 #payload = self.request('start', 'post')
694
695 except Exception as e:
696 if 'No route to host' not in str(e):
697 self.device.status = 4
698 else:
699 self.device.status = 0
700 self.message = 'RC write: {}'.format(str(e))
701 self.device.save()
702 return False
703
704 return True
705
706 def get_absolute_url_import(self):
707 return reverse('url_import_usrp_rx_conf', args=[str(self.id)])
708
709
710
@@ -0,0 +1,2
1 .bk-bs-container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media(min-width:768px){.bk-bs-container{width:750px}}@media(min-width:992px){.bk-bs-container{width:970px}}@media(min-width:1200px){.bk-bs-container{width:1170px}}.bk-bs-container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.bk-bs-row{margin-left:-15px;margin-right:-15px}.bk-bs-col-xs-1,.bk-bs-col-sm-1,.bk-bs-col-md-1,.bk-bs-col-lg-1,.bk-bs-col-xs-2,.bk-bs-col-sm-2,.bk-bs-col-md-2,.bk-bs-col-lg-2,.bk-bs-col-xs-3,.bk-bs-col-sm-3,.bk-bs-col-md-3,.bk-bs-col-lg-3,.bk-bs-col-xs-4,.bk-bs-col-sm-4,.bk-bs-col-md-4,.bk-bs-col-lg-4,.bk-bs-col-xs-5,.bk-bs-col-sm-5,.bk-bs-col-md-5,.bk-bs-col-lg-5,.bk-bs-col-xs-6,.bk-bs-col-sm-6,.bk-bs-col-md-6,.bk-bs-col-lg-6,.bk-bs-col-xs-7,.bk-bs-col-sm-7,.bk-bs-col-md-7,.bk-bs-col-lg-7,.bk-bs-col-xs-8,.bk-bs-col-sm-8,.bk-bs-col-md-8,.bk-bs-col-lg-8,.bk-bs-col-xs-9,.bk-bs-col-sm-9,.bk-bs-col-md-9,.bk-bs-col-lg-9,.bk-bs-col-xs-10,.bk-bs-col-sm-10,.bk-bs-col-md-10,.bk-bs-col-lg-10,.bk-bs-col-xs-11,.bk-bs-col-sm-11,.bk-bs-col-md-11,.bk-bs-col-lg-11,.bk-bs-col-xs-12,.bk-bs-col-sm-12,.bk-bs-col-md-12,.bk-bs-col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.bk-bs-col-xs-1,.bk-bs-col-xs-2,.bk-bs-col-xs-3,.bk-bs-col-xs-4,.bk-bs-col-xs-5,.bk-bs-col-xs-6,.bk-bs-col-xs-7,.bk-bs-col-xs-8,.bk-bs-col-xs-9,.bk-bs-col-xs-10,.bk-bs-col-xs-11,.bk-bs-col-xs-12{float:left}.bk-bs-col-xs-12{width:100%}.bk-bs-col-xs-11{width:91.66666667%}.bk-bs-col-xs-10{width:83.33333333%}.bk-bs-col-xs-9{width:75%}.bk-bs-col-xs-8{width:66.66666667%}.bk-bs-col-xs-7{width:58.33333333%}.bk-bs-col-xs-6{width:50%}.bk-bs-col-xs-5{width:41.66666667%}.bk-bs-col-xs-4{width:33.33333333%}.bk-bs-col-xs-3{width:25%}.bk-bs-col-xs-2{width:16.66666667%}.bk-bs-col-xs-1{width:8.33333333%}.bk-bs-col-xs-pull-12{right:100%}.bk-bs-col-xs-pull-11{right:91.66666667%}.bk-bs-col-xs-pull-10{right:83.33333333%}.bk-bs-col-xs-pull-9{right:75%}.bk-bs-col-xs-pull-8{right:66.66666667%}.bk-bs-col-xs-pull-7{right:58.33333333%}.bk-bs-col-xs-pull-6{right:50%}.bk-bs-col-xs-pull-5{right:41.66666667%}.bk-bs-col-xs-pull-4{right:33.33333333%}.bk-bs-col-xs-pull-3{right:25%}.bk-bs-col-xs-pull-2{right:16.66666667%}.bk-bs-col-xs-pull-1{right:8.33333333%}.bk-bs-col-xs-pull-0{right:0}.bk-bs-col-xs-push-12{left:100%}.bk-bs-col-xs-push-11{left:91.66666667%}.bk-bs-col-xs-push-10{left:83.33333333%}.bk-bs-col-xs-push-9{left:75%}.bk-bs-col-xs-push-8{left:66.66666667%}.bk-bs-col-xs-push-7{left:58.33333333%}.bk-bs-col-xs-push-6{left:50%}.bk-bs-col-xs-push-5{left:41.66666667%}.bk-bs-col-xs-push-4{left:33.33333333%}.bk-bs-col-xs-push-3{left:25%}.bk-bs-col-xs-push-2{left:16.66666667%}.bk-bs-col-xs-push-1{left:8.33333333%}.bk-bs-col-xs-push-0{left:0}.bk-bs-col-xs-offset-12{margin-left:100%}.bk-bs-col-xs-offset-11{margin-left:91.66666667%}.bk-bs-col-xs-offset-10{margin-left:83.33333333%}.bk-bs-col-xs-offset-9{margin-left:75%}.bk-bs-col-xs-offset-8{margin-left:66.66666667%}.bk-bs-col-xs-offset-7{margin-left:58.33333333%}.bk-bs-col-xs-offset-6{margin-left:50%}.bk-bs-col-xs-offset-5{margin-left:41.66666667%}.bk-bs-col-xs-offset-4{margin-left:33.33333333%}.bk-bs-col-xs-offset-3{margin-left:25%}.bk-bs-col-xs-offset-2{margin-left:16.66666667%}.bk-bs-col-xs-offset-1{margin-left:8.33333333%}.bk-bs-col-xs-offset-0{margin-left:0}@media(min-width:768px){.bk-bs-col-sm-1,.bk-bs-col-sm-2,.bk-bs-col-sm-3,.bk-bs-col-sm-4,.bk-bs-col-sm-5,.bk-bs-col-sm-6,.bk-bs-col-sm-7,.bk-bs-col-sm-8,.bk-bs-col-sm-9,.bk-bs-col-sm-10,.bk-bs-col-sm-11,.bk-bs-col-sm-12{float:left}.bk-bs-col-sm-12{width:100%}.bk-bs-col-sm-11{width:91.66666667%}.bk-bs-col-sm-10{width:83.33333333%}.bk-bs-col-sm-9{width:75%}.bk-bs-col-sm-8{width:66.66666667%}.bk-bs-col-sm-7{width:58.33333333%}.bk-bs-col-sm-6{width:50%}.bk-bs-col-sm-5{width:41.66666667%}.bk-bs-col-sm-4{width:33.33333333%}.bk-bs-col-sm-3{width:25%}.bk-bs-col-sm-2{width:16.66666667%}.bk-bs-col-sm-1{width:8.33333333%}.bk-bs-col-sm-pull-12{right:100%}.bk-bs-col-sm-pull-11{right:91.66666667%}.bk-bs-col-sm-pull-10{right:83.33333333%}.bk-bs-col-sm-pull-9{right:75%}.bk-bs-col-sm-pull-8{right:66.66666667%}.bk-bs-col-sm-pull-7{right:58.33333333%}.bk-bs-col-sm-pull-6{right:50%}.bk-bs-col-sm-pull-5{right:41.66666667%}.bk-bs-col-sm-pull-4{right:33.33333333%}.bk-bs-col-sm-pull-3{right:25%}.bk-bs-col-sm-pull-2{right:16.66666667%}.bk-bs-col-sm-pull-1{right:8.33333333%}.bk-bs-col-sm-pull-0{right:0}.bk-bs-col-sm-push-12{left:100%}.bk-bs-col-sm-push-11{left:91.66666667%}.bk-bs-col-sm-push-10{left:83.33333333%}.bk-bs-col-sm-push-9{left:75%}.bk-bs-col-sm-push-8{left:66.66666667%}.bk-bs-col-sm-push-7{left:58.33333333%}.bk-bs-col-sm-push-6{left:50%}.bk-bs-col-sm-push-5{left:41.66666667%}.bk-bs-col-sm-push-4{left:33.33333333%}.bk-bs-col-sm-push-3{left:25%}.bk-bs-col-sm-push-2{left:16.66666667%}.bk-bs-col-sm-push-1{left:8.33333333%}.bk-bs-col-sm-push-0{left:0}.bk-bs-col-sm-offset-12{margin-left:100%}.bk-bs-col-sm-offset-11{margin-left:91.66666667%}.bk-bs-col-sm-offset-10{margin-left:83.33333333%}.bk-bs-col-sm-offset-9{margin-left:75%}.bk-bs-col-sm-offset-8{margin-left:66.66666667%}.bk-bs-col-sm-offset-7{margin-left:58.33333333%}.bk-bs-col-sm-offset-6{margin-left:50%}.bk-bs-col-sm-offset-5{margin-left:41.66666667%}.bk-bs-col-sm-offset-4{margin-left:33.33333333%}.bk-bs-col-sm-offset-3{margin-left:25%}.bk-bs-col-sm-offset-2{margin-left:16.66666667%}.bk-bs-col-sm-offset-1{margin-left:8.33333333%}.bk-bs-col-sm-offset-0{margin-left:0}}@media(min-width:992px){.bk-bs-col-md-1,.bk-bs-col-md-2,.bk-bs-col-md-3,.bk-bs-col-md-4,.bk-bs-col-md-5,.bk-bs-col-md-6,.bk-bs-col-md-7,.bk-bs-col-md-8,.bk-bs-col-md-9,.bk-bs-col-md-10,.bk-bs-col-md-11,.bk-bs-col-md-12{float:left}.bk-bs-col-md-12{width:100%}.bk-bs-col-md-11{width:91.66666667%}.bk-bs-col-md-10{width:83.33333333%}.bk-bs-col-md-9{width:75%}.bk-bs-col-md-8{width:66.66666667%}.bk-bs-col-md-7{width:58.33333333%}.bk-bs-col-md-6{width:50%}.bk-bs-col-md-5{width:41.66666667%}.bk-bs-col-md-4{width:33.33333333%}.bk-bs-col-md-3{width:25%}.bk-bs-col-md-2{width:16.66666667%}.bk-bs-col-md-1{width:8.33333333%}.bk-bs-col-md-pull-12{right:100%}.bk-bs-col-md-pull-11{right:91.66666667%}.bk-bs-col-md-pull-10{right:83.33333333%}.bk-bs-col-md-pull-9{right:75%}.bk-bs-col-md-pull-8{right:66.66666667%}.bk-bs-col-md-pull-7{right:58.33333333%}.bk-bs-col-md-pull-6{right:50%}.bk-bs-col-md-pull-5{right:41.66666667%}.bk-bs-col-md-pull-4{right:33.33333333%}.bk-bs-col-md-pull-3{right:25%}.bk-bs-col-md-pull-2{right:16.66666667%}.bk-bs-col-md-pull-1{right:8.33333333%}.bk-bs-col-md-pull-0{right:0}.bk-bs-col-md-push-12{left:100%}.bk-bs-col-md-push-11{left:91.66666667%}.bk-bs-col-md-push-10{left:83.33333333%}.bk-bs-col-md-push-9{left:75%}.bk-bs-col-md-push-8{left:66.66666667%}.bk-bs-col-md-push-7{left:58.33333333%}.bk-bs-col-md-push-6{left:50%}.bk-bs-col-md-push-5{left:41.66666667%}.bk-bs-col-md-push-4{left:33.33333333%}.bk-bs-col-md-push-3{left:25%}.bk-bs-col-md-push-2{left:16.66666667%}.bk-bs-col-md-push-1{left:8.33333333%}.bk-bs-col-md-push-0{left:0}.bk-bs-col-md-offset-12{margin-left:100%}.bk-bs-col-md-offset-11{margin-left:91.66666667%}.bk-bs-col-md-offset-10{margin-left:83.33333333%}.bk-bs-col-md-offset-9{margin-left:75%}.bk-bs-col-md-offset-8{margin-left:66.66666667%}.bk-bs-col-md-offset-7{margin-left:58.33333333%}.bk-bs-col-md-offset-6{margin-left:50%}.bk-bs-col-md-offset-5{margin-left:41.66666667%}.bk-bs-col-md-offset-4{margin-left:33.33333333%}.bk-bs-col-md-offset-3{margin-left:25%}.bk-bs-col-md-offset-2{margin-left:16.66666667%}.bk-bs-col-md-offset-1{margin-left:8.33333333%}.bk-bs-col-md-offset-0{margin-left:0}}@media(min-width:1200px){.bk-bs-col-lg-1,.bk-bs-col-lg-2,.bk-bs-col-lg-3,.bk-bs-col-lg-4,.bk-bs-col-lg-5,.bk-bs-col-lg-6,.bk-bs-col-lg-7,.bk-bs-col-lg-8,.bk-bs-col-lg-9,.bk-bs-col-lg-10,.bk-bs-col-lg-11,.bk-bs-col-lg-12{float:left}.bk-bs-col-lg-12{width:100%}.bk-bs-col-lg-11{width:91.66666667%}.bk-bs-col-lg-10{width:83.33333333%}.bk-bs-col-lg-9{width:75%}.bk-bs-col-lg-8{width:66.66666667%}.bk-bs-col-lg-7{width:58.33333333%}.bk-bs-col-lg-6{width:50%}.bk-bs-col-lg-5{width:41.66666667%}.bk-bs-col-lg-4{width:33.33333333%}.bk-bs-col-lg-3{width:25%}.bk-bs-col-lg-2{width:16.66666667%}.bk-bs-col-lg-1{width:8.33333333%}.bk-bs-col-lg-pull-12{right:100%}.bk-bs-col-lg-pull-11{right:91.66666667%}.bk-bs-col-lg-pull-10{right:83.33333333%}.bk-bs-col-lg-pull-9{right:75%}.bk-bs-col-lg-pull-8{right:66.66666667%}.bk-bs-col-lg-pull-7{right:58.33333333%}.bk-bs-col-lg-pull-6{right:50%}.bk-bs-col-lg-pull-5{right:41.66666667%}.bk-bs-col-lg-pull-4{right:33.33333333%}.bk-bs-col-lg-pull-3{right:25%}.bk-bs-col-lg-pull-2{right:16.66666667%}.bk-bs-col-lg-pull-1{right:8.33333333%}.bk-bs-col-lg-pull-0{right:0}.bk-bs-col-lg-push-12{left:100%}.bk-bs-col-lg-push-11{left:91.66666667%}.bk-bs-col-lg-push-10{left:83.33333333%}.bk-bs-col-lg-push-9{left:75%}.bk-bs-col-lg-push-8{left:66.66666667%}.bk-bs-col-lg-push-7{left:58.33333333%}.bk-bs-col-lg-push-6{left:50%}.bk-bs-col-lg-push-5{left:41.66666667%}.bk-bs-col-lg-push-4{left:33.33333333%}.bk-bs-col-lg-push-3{left:25%}.bk-bs-col-lg-push-2{left:16.66666667%}.bk-bs-col-lg-push-1{left:8.33333333%}.bk-bs-col-lg-push-0{left:0}.bk-bs-col-lg-offset-12{margin-left:100%}.bk-bs-col-lg-offset-11{margin-left:91.66666667%}.bk-bs-col-lg-offset-10{margin-left:83.33333333%}.bk-bs-col-lg-offset-9{margin-left:75%}.bk-bs-col-lg-offset-8{margin-left:66.66666667%}.bk-bs-col-lg-offset-7{margin-left:58.33333333%}.bk-bs-col-lg-offset-6{margin-left:50%}.bk-bs-col-lg-offset-5{margin-left:41.66666667%}.bk-bs-col-lg-offset-4{margin-left:33.33333333%}.bk-bs-col-lg-offset-3{margin-left:25%}.bk-bs-col-lg-offset-2{margin-left:16.66666667%}.bk-bs-col-lg-offset-1{margin-left:8.33333333%}.bk-bs-col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.bk-bs-table{width:100%;margin-bottom:20px}.bk-bs-table>thead>tr>th,.bk-bs-table>tbody>tr>th,.bk-bs-table>tfoot>tr>th,.bk-bs-table>thead>tr>td,.bk-bs-table>tbody>tr>td,.bk-bs-table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.bk-bs-table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.bk-bs-table>caption+thead>tr:first-child>th,.bk-bs-table>colgroup+thead>tr:first-child>th,.bk-bs-table>thead:first-child>tr:first-child>th,.bk-bs-table>caption+thead>tr:first-child>td,.bk-bs-table>colgroup+thead>tr:first-child>td,.bk-bs-table>thead:first-child>tr:first-child>td{border-top:0}.bk-bs-table>tbody+tbody{border-top:2px solid #ddd}.bk-bs-table .bk-bs-table{background-color:#fff}.bk-bs-table-condensed>thead>tr>th,.bk-bs-table-condensed>tbody>tr>th,.bk-bs-table-condensed>tfoot>tr>th,.bk-bs-table-condensed>thead>tr>td,.bk-bs-table-condensed>tbody>tr>td,.bk-bs-table-condensed>tfoot>tr>td{padding:5px}.bk-bs-table-bordered{border:1px solid #ddd}.bk-bs-table-bordered>thead>tr>th,.bk-bs-table-bordered>tbody>tr>th,.bk-bs-table-bordered>tfoot>tr>th,.bk-bs-table-bordered>thead>tr>td,.bk-bs-table-bordered>tbody>tr>td,.bk-bs-table-bordered>tfoot>tr>td{border:1px solid #ddd}.bk-bs-table-bordered>thead>tr>th,.bk-bs-table-bordered>thead>tr>td{border-bottom-width:2px}.bk-bs-table-striped>tbody>tr:nth-child(odd)>td,.bk-bs-table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.bk-bs-table-hover>tbody>tr:hover>td,.bk-bs-table-hover>tbody>tr:hover>th{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}.bk-bs-table>thead>tr>td.active,.bk-bs-table>tbody>tr>td.active,.bk-bs-table>tfoot>tr>td.active,.bk-bs-table>thead>tr>th.active,.bk-bs-table>tbody>tr>th.active,.bk-bs-table>tfoot>tr>th.active,.bk-bs-table>thead>tr.active>td,.bk-bs-table>tbody>tr.active>td,.bk-bs-table>tfoot>tr.active>td,.bk-bs-table>thead>tr.active>th,.bk-bs-table>tbody>tr.active>th,.bk-bs-table>tfoot>tr.active>th{background-color:#f5f5f5}.bk-bs-table-hover>tbody>tr>td.active:hover,.bk-bs-table-hover>tbody>tr>th.active:hover,.bk-bs-table-hover>tbody>tr.active:hover>td,.bk-bs-table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.bk-bs-table>thead>tr>td.success,.bk-bs-table>tbody>tr>td.success,.bk-bs-table>tfoot>tr>td.success,.bk-bs-table>thead>tr>th.success,.bk-bs-table>tbody>tr>th.success,.bk-bs-table>tfoot>tr>th.success,.bk-bs-table>thead>tr.success>td,.bk-bs-table>tbody>tr.success>td,.bk-bs-table>tfoot>tr.success>td,.bk-bs-table>thead>tr.success>th,.bk-bs-table>tbody>tr.success>th,.bk-bs-table>tfoot>tr.success>th{background-color:#dff0d8}.bk-bs-table-hover>tbody>tr>td.success:hover,.bk-bs-table-hover>tbody>tr>th.success:hover,.bk-bs-table-hover>tbody>tr.success:hover>td,.bk-bs-table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.bk-bs-table>thead>tr>td.info,.bk-bs-table>tbody>tr>td.info,.bk-bs-table>tfoot>tr>td.info,.bk-bs-table>thead>tr>th.info,.bk-bs-table>tbody>tr>th.info,.bk-bs-table>tfoot>tr>th.info,.bk-bs-table>thead>tr.info>td,.bk-bs-table>tbody>tr.info>td,.bk-bs-table>tfoot>tr.info>td,.bk-bs-table>thead>tr.info>th,.bk-bs-table>tbody>tr.info>th,.bk-bs-table>tfoot>tr.info>th{background-color:#d9edf7}.bk-bs-table-hover>tbody>tr>td.info:hover,.bk-bs-table-hover>tbody>tr>th.info:hover,.bk-bs-table-hover>tbody>tr.info:hover>td,.bk-bs-table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.bk-bs-table>thead>tr>td.warning,.bk-bs-table>tbody>tr>td.warning,.bk-bs-table>tfoot>tr>td.warning,.bk-bs-table>thead>tr>th.warning,.bk-bs-table>tbody>tr>th.warning,.bk-bs-table>tfoot>tr>th.warning,.bk-bs-table>thead>tr.warning>td,.bk-bs-table>tbody>tr.warning>td,.bk-bs-table>tfoot>tr.warning>td,.bk-bs-table>thead>tr.warning>th,.bk-bs-table>tbody>tr.warning>th,.bk-bs-table>tfoot>tr.warning>th{background-color:#fcf8e3}.bk-bs-table-hover>tbody>tr>td.warning:hover,.bk-bs-table-hover>tbody>tr>th.warning:hover,.bk-bs-table-hover>tbody>tr.warning:hover>td,.bk-bs-table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.bk-bs-table>thead>tr>td.danger,.bk-bs-table>tbody>tr>td.danger,.bk-bs-table>tfoot>tr>td.danger,.bk-bs-table>thead>tr>th.danger,.bk-bs-table>tbody>tr>th.danger,.bk-bs-table>tfoot>tr>th.danger,.bk-bs-table>thead>tr.danger>td,.bk-bs-table>tbody>tr.danger>td,.bk-bs-table>tfoot>tr.danger>td,.bk-bs-table>thead>tr.danger>th,.bk-bs-table>tbody>tr.danger>th,.bk-bs-table>tfoot>tr.danger>th{background-color:#f2dede}.bk-bs-table-hover>tbody>tr>td.danger:hover,.bk-bs-table-hover>tbody>tr>th.danger:hover,.bk-bs-table-hover>tbody>tr.danger:hover>td,.bk-bs-table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media(max-width:767px){.bk-bs-table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.bk-bs-table-responsive>.bk-bs-table{margin-bottom:0}.bk-bs-table-responsive>.bk-bs-table>thead>tr>th,.bk-bs-table-responsive>.bk-bs-table>tbody>tr>th,.bk-bs-table-responsive>.bk-bs-table>tfoot>tr>th,.bk-bs-table-responsive>.bk-bs-table>thead>tr>td,.bk-bs-table-responsive>.bk-bs-table>tbody>tr>td,.bk-bs-table-responsive>.bk-bs-table>tfoot>tr>td{white-space:nowrap}.bk-bs-table-responsive>.bk-bs-table-bordered{border:0}.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>th:first-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>th:first-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>th:first-child,.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>td:first-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>td:first-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>td:first-child{border-left:0}.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>th:last-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>th:last-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>th:last-child,.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>td:last-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>td:last-child,.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>td:last-child{border-right:0}.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:last-child>th,.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr:last-child>th,.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:last-child>td,.bk-bs-table-responsive>.bk-bs-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:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;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:14px;line-height:1.42857143;color:#555}.bk-bs-form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-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}.bk-bs-form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6)}.bk-bs-form-control::-moz-placeholder{color:#999;opacity:1}.bk-bs-form-control:-ms-input-placeholder{color:#999}.bk-bs-form-control::-webkit-input-placeholder{color:#999}.bk-bs-form-control[disabled],.bk-bs-form-control[readonly],fieldset[disabled] .bk-bs-form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.bk-bs-form-control{height:auto}input[type="search"]{-webkit-appearance:none}input[type="date"]{line-height:34px}.bk-bs-form-group{margin-bottom:15px}.bk-bs-radio,.bk-bs-checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.bk-bs-radio label,.bk-bs-checkbox label{display:inline;font-weight:normal;cursor:pointer}.bk-bs-radio input[type="radio"],.bk-bs-radio-inline input[type="radio"],.bk-bs-checkbox input[type="checkbox"],.bk-bs-checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.bk-bs-radio+.bk-bs-radio,.bk-bs-checkbox+.bk-bs-checkbox{margin-top:-5px}.bk-bs-radio-inline,.bk-bs-checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.bk-bs-radio-inline+.bk-bs-radio-inline,.bk-bs-checkbox-inline+.bk-bs-checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.bk-bs-radio[disabled],.bk-bs-radio-inline[disabled],.bk-bs-checkbox[disabled],.bk-bs-checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .bk-bs-radio,fieldset[disabled] .bk-bs-radio-inline,fieldset[disabled] .bk-bs-checkbox,fieldset[disabled] .bk-bs-checkbox-inline{cursor:not-allowed}.bk-bs-input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.bk-bs-input-sm{height:30px;line-height:30px}textarea.bk-bs-input-sm,select[multiple].bk-bs-input-sm{height:auto}.bk-bs-input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.bk-bs-input-lg{height:46px;line-height:46px}textarea.bk-bs-input-lg,select[multiple].bk-bs-input-lg{height:auto}.bk-bs-has-feedback{position:relative}.bk-bs-has-feedback .bk-bs-form-control{padding-right:42.5px}.bk-bs-has-feedback .bk-bs-form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.bk-bs-has-success .bk-bs-help-block,.bk-bs-has-success .bk-bs-control-label,.bk-bs-has-success .bk-bs-radio,.bk-bs-has-success .bk-bs-checkbox,.bk-bs-has-success .bk-bs-radio-inline,.bk-bs-has-success .bk-bs-checkbox-inline{color:#3c763d}.bk-bs-has-success .bk-bs-form-control{border-color:#3c763d;-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)}.bk-bs-has-success .bk-bs-form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.bk-bs-has-success .bk-bs-input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.bk-bs-has-success .bk-bs-form-control-feedback{color:#3c763d}.bk-bs-has-warning .bk-bs-help-block,.bk-bs-has-warning .bk-bs-control-label,.bk-bs-has-warning .bk-bs-radio,.bk-bs-has-warning .bk-bs-checkbox,.bk-bs-has-warning .bk-bs-radio-inline,.bk-bs-has-warning .bk-bs-checkbox-inline{color:#8a6d3b}.bk-bs-has-warning .bk-bs-form-control{border-color:#8a6d3b;-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)}.bk-bs-has-warning .bk-bs-form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.bk-bs-has-warning .bk-bs-input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.bk-bs-has-warning .bk-bs-form-control-feedback{color:#8a6d3b}.bk-bs-has-error .bk-bs-help-block,.bk-bs-has-error .bk-bs-control-label,.bk-bs-has-error .bk-bs-radio,.bk-bs-has-error .bk-bs-checkbox,.bk-bs-has-error .bk-bs-radio-inline,.bk-bs-has-error .bk-bs-checkbox-inline{color:#a94442}.bk-bs-has-error .bk-bs-form-control{border-color:#a94442;-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)}.bk-bs-has-error .bk-bs-form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.bk-bs-has-error .bk-bs-input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.bk-bs-has-error .bk-bs-form-control-feedback{color:#a94442}.bk-bs-form-control-static{margin-bottom:0}.bk-bs-help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media(min-width:768px){.bk-bs-form-inline .bk-bs-form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.bk-bs-form-inline .bk-bs-form-control{display:inline-block;width:auto;vertical-align:middle}.bk-bs-form-inline .bk-bs-input-group>.bk-bs-form-control{width:100%}.bk-bs-form-inline .bk-bs-control-label{margin-bottom:0;vertical-align:middle}.bk-bs-form-inline .bk-bs-radio,.bk-bs-form-inline .bk-bs-checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.bk-bs-form-inline .bk-bs-radio input[type="radio"],.bk-bs-form-inline .bk-bs-checkbox input[type="checkbox"]{float:none;margin-left:0}.bk-bs-form-inline .bk-bs-has-feedback .bk-bs-form-control-feedback{top:0}}.bk-bs-form-horizontal .bk-bs-control-label,.bk-bs-form-horizontal .bk-bs-radio,.bk-bs-form-horizontal .bk-bs-checkbox,.bk-bs-form-horizontal .bk-bs-radio-inline,.bk-bs-form-horizontal .bk-bs-checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.bk-bs-form-horizontal .bk-bs-radio,.bk-bs-form-horizontal .bk-bs-checkbox{min-height:27px}.bk-bs-form-horizontal .bk-bs-form-group{margin-left:-15px;margin-right:-15px}.bk-bs-form-horizontal .bk-bs-form-control-static{padding-top:7px}@media(min-width:768px){.bk-bs-form-horizontal .bk-bs-control-label{text-align:right}}.bk-bs-form-horizontal .bk-bs-has-feedback .bk-bs-form-control-feedback{top:0;right:15px}.bk-bs-btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 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}.bk-bs-btn:focus,.bk-bs-btn:active:focus,.bk-bs-btn.bk-bs-active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.bk-bs-btn:hover,.bk-bs-btn:focus{color:#333;text-decoration:none}.bk-bs-btn:active,.bk-bs-btn.bk-bs-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)}.bk-bs-btn.bk-bs-disabled,.bk-bs-btn[disabled],fieldset[disabled] .bk-bs-btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.bk-bs-btn-default{color:#333;background-color:#fff;border-color:#ccc}.bk-bs-btn-default:hover,.bk-bs-btn-default:focus,.bk-bs-btn-default:active,.bk-bs-btn-default.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.bk-bs-btn-default:active,.bk-bs-btn-default.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-default{background-image:none}.bk-bs-btn-default.bk-bs-disabled,.bk-bs-btn-default[disabled],fieldset[disabled] .bk-bs-btn-default,.bk-bs-btn-default.bk-bs-disabled:hover,.bk-bs-btn-default[disabled]:hover,fieldset[disabled] .bk-bs-btn-default:hover,.bk-bs-btn-default.bk-bs-disabled:focus,.bk-bs-btn-default[disabled]:focus,fieldset[disabled] .bk-bs-btn-default:focus,.bk-bs-btn-default.bk-bs-disabled:active,.bk-bs-btn-default[disabled]:active,fieldset[disabled] .bk-bs-btn-default:active,.bk-bs-btn-default.bk-bs-disabled.bk-bs-active,.bk-bs-btn-default[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-default.bk-bs-active{background-color:#fff;border-color:#ccc}.bk-bs-btn-default .bk-bs-badge{color:#fff;background-color:#333}.bk-bs-btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.bk-bs-btn-primary:hover,.bk-bs-btn-primary:focus,.bk-bs-btn-primary:active,.bk-bs-btn-primary.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.bk-bs-btn-primary:active,.bk-bs-btn-primary.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-primary{background-image:none}.bk-bs-btn-primary.bk-bs-disabled,.bk-bs-btn-primary[disabled],fieldset[disabled] .bk-bs-btn-primary,.bk-bs-btn-primary.bk-bs-disabled:hover,.bk-bs-btn-primary[disabled]:hover,fieldset[disabled] .bk-bs-btn-primary:hover,.bk-bs-btn-primary.bk-bs-disabled:focus,.bk-bs-btn-primary[disabled]:focus,fieldset[disabled] .bk-bs-btn-primary:focus,.bk-bs-btn-primary.bk-bs-disabled:active,.bk-bs-btn-primary[disabled]:active,fieldset[disabled] .bk-bs-btn-primary:active,.bk-bs-btn-primary.bk-bs-disabled.bk-bs-active,.bk-bs-btn-primary[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-primary.bk-bs-active{background-color:#428bca;border-color:#357ebd}.bk-bs-btn-primary .bk-bs-badge{color:#428bca;background-color:#fff}.bk-bs-btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.bk-bs-btn-success:hover,.bk-bs-btn-success:focus,.bk-bs-btn-success:active,.bk-bs-btn-success.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-success{color:#fff;background-color:#47a447;border-color:#398439}.bk-bs-btn-success:active,.bk-bs-btn-success.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-success{background-image:none}.bk-bs-btn-success.bk-bs-disabled,.bk-bs-btn-success[disabled],fieldset[disabled] .bk-bs-btn-success,.bk-bs-btn-success.bk-bs-disabled:hover,.bk-bs-btn-success[disabled]:hover,fieldset[disabled] .bk-bs-btn-success:hover,.bk-bs-btn-success.bk-bs-disabled:focus,.bk-bs-btn-success[disabled]:focus,fieldset[disabled] .bk-bs-btn-success:focus,.bk-bs-btn-success.bk-bs-disabled:active,.bk-bs-btn-success[disabled]:active,fieldset[disabled] .bk-bs-btn-success:active,.bk-bs-btn-success.bk-bs-disabled.bk-bs-active,.bk-bs-btn-success[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-success.bk-bs-active{background-color:#5cb85c;border-color:#4cae4c}.bk-bs-btn-success .bk-bs-badge{color:#5cb85c;background-color:#fff}.bk-bs-btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.bk-bs-btn-info:hover,.bk-bs-btn-info:focus,.bk-bs-btn-info:active,.bk-bs-btn-info.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.bk-bs-btn-info:active,.bk-bs-btn-info.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-info{background-image:none}.bk-bs-btn-info.bk-bs-disabled,.bk-bs-btn-info[disabled],fieldset[disabled] .bk-bs-btn-info,.bk-bs-btn-info.bk-bs-disabled:hover,.bk-bs-btn-info[disabled]:hover,fieldset[disabled] .bk-bs-btn-info:hover,.bk-bs-btn-info.bk-bs-disabled:focus,.bk-bs-btn-info[disabled]:focus,fieldset[disabled] .bk-bs-btn-info:focus,.bk-bs-btn-info.bk-bs-disabled:active,.bk-bs-btn-info[disabled]:active,fieldset[disabled] .bk-bs-btn-info:active,.bk-bs-btn-info.bk-bs-disabled.bk-bs-active,.bk-bs-btn-info[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-info.bk-bs-active{background-color:#5bc0de;border-color:#46b8da}.bk-bs-btn-info .bk-bs-badge{color:#5bc0de;background-color:#fff}.bk-bs-btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.bk-bs-btn-warning:hover,.bk-bs-btn-warning:focus,.bk-bs-btn-warning:active,.bk-bs-btn-warning.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.bk-bs-btn-warning:active,.bk-bs-btn-warning.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-warning{background-image:none}.bk-bs-btn-warning.bk-bs-disabled,.bk-bs-btn-warning[disabled],fieldset[disabled] .bk-bs-btn-warning,.bk-bs-btn-warning.bk-bs-disabled:hover,.bk-bs-btn-warning[disabled]:hover,fieldset[disabled] .bk-bs-btn-warning:hover,.bk-bs-btn-warning.bk-bs-disabled:focus,.bk-bs-btn-warning[disabled]:focus,fieldset[disabled] .bk-bs-btn-warning:focus,.bk-bs-btn-warning.bk-bs-disabled:active,.bk-bs-btn-warning[disabled]:active,fieldset[disabled] .bk-bs-btn-warning:active,.bk-bs-btn-warning.bk-bs-disabled.bk-bs-active,.bk-bs-btn-warning[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-warning.bk-bs-active{background-color:#f0ad4e;border-color:#eea236}.bk-bs-btn-warning .bk-bs-badge{color:#f0ad4e;background-color:#fff}.bk-bs-btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.bk-bs-btn-danger:hover,.bk-bs-btn-danger:focus,.bk-bs-btn-danger:active,.bk-bs-btn-danger.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.bk-bs-btn-danger:active,.bk-bs-btn-danger.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-danger{background-image:none}.bk-bs-btn-danger.bk-bs-disabled,.bk-bs-btn-danger[disabled],fieldset[disabled] .bk-bs-btn-danger,.bk-bs-btn-danger.bk-bs-disabled:hover,.bk-bs-btn-danger[disabled]:hover,fieldset[disabled] .bk-bs-btn-danger:hover,.bk-bs-btn-danger.bk-bs-disabled:focus,.bk-bs-btn-danger[disabled]:focus,fieldset[disabled] .bk-bs-btn-danger:focus,.bk-bs-btn-danger.bk-bs-disabled:active,.bk-bs-btn-danger[disabled]:active,fieldset[disabled] .bk-bs-btn-danger:active,.bk-bs-btn-danger.bk-bs-disabled.bk-bs-active,.bk-bs-btn-danger[disabled].bk-bs-active,fieldset[disabled] .bk-bs-btn-danger.bk-bs-active{background-color:#d9534f;border-color:#d43f3a}.bk-bs-btn-danger .bk-bs-badge{color:#d9534f;background-color:#fff}.bk-bs-btn-link{color:#428bca;font-weight:normal;cursor:pointer;border-radius:0}.bk-bs-btn-link,.bk-bs-btn-link:active,.bk-bs-btn-link[disabled],fieldset[disabled] .bk-bs-btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.bk-bs-btn-link,.bk-bs-btn-link:hover,.bk-bs-btn-link:focus,.bk-bs-btn-link:active{border-color:transparent}.bk-bs-btn-link:hover,.bk-bs-btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.bk-bs-btn-link[disabled]:hover,fieldset[disabled] .bk-bs-btn-link:hover,.bk-bs-btn-link[disabled]:focus,fieldset[disabled] .bk-bs-btn-link:focus{color:#999;text-decoration:none}.bk-bs-btn-lg,.bk-bs-btn-group-lg>.bk-bs-btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.bk-bs-btn-sm,.bk-bs-btn-group-sm>.bk-bs-btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.bk-bs-btn-xs,.bk-bs-btn-group-xs>.bk-bs-btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.bk-bs-btn-block{display:block;width:100%;padding-left:0;padding-right:0}.bk-bs-btn-block+.bk-bs-btn-block{margin-top:5px}input[type="submit"].bk-bs-btn-block,input[type="reset"].bk-bs-btn-block,input[type="button"].bk-bs-btn-block{width:100%}.bk-bs-caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.bk-bs-dropdown{position:relative}.bk-bs-dropdown-toggle:focus{outline:0}.bk-bs-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;background-color:#fff;border:1px solid #ccc;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);background-clip:padding-box}.bk-bs-dropdown-menu.bk-bs-pull-right{right:0;left:auto}.bk-bs-dropdown-menu .bk-bs-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.bk-bs-dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.bk-bs-dropdown-menu>li>a:hover,.bk-bs-dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.bk-bs-dropdown-menu>.bk-bs-active>a,.bk-bs-dropdown-menu>.bk-bs-active>a:hover,.bk-bs-dropdown-menu>.bk-bs-active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.bk-bs-dropdown-menu>.bk-bs-disabled>a,.bk-bs-dropdown-menu>.bk-bs-disabled>a:hover,.bk-bs-dropdown-menu>.bk-bs-disabled>a:focus{color:#999}.bk-bs-dropdown-menu>.bk-bs-disabled>a:hover,.bk-bs-dropdown-menu>.bk-bs-disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.bk-bs-Microsoft.bk-bs-gradient(enabled = false);cursor:not-allowed}.bk-bs-open>.bk-bs-dropdown-menu{display:block}.bk-bs-open>a{outline:0}.bk-bs-dropdown-menu-right{left:auto;right:0}.bk-bs-dropdown-menu-left{left:0;right:auto}.bk-bs-dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.bk-bs-dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.bk-bs-pull-right>.bk-bs-dropdown-menu{right:0;left:auto}.bk-bs-dropup .bk-bs-caret,.bk-bs-navbar-fixed-bottom .bk-bs-dropdown .bk-bs-caret{border-top:0;border-bottom:4px solid;content:""}.bk-bs-dropup .bk-bs-dropdown-menu,.bk-bs-navbar-fixed-bottom .bk-bs-dropdown .bk-bs-dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media(min-width:768px){.bk-bs-navbar-right .bk-bs-dropdown-menu{left:auto;right:0}.bk-bs-navbar-right .bk-bs-dropdown-menu-left{left:0;right:auto}}.bk-bs-btn-group,.bk-bs-btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.bk-bs-btn-group>.bk-bs-btn,.bk-bs-btn-group-vertical>.bk-bs-btn{position:relative;float:left}.bk-bs-btn-group>.bk-bs-btn:hover,.bk-bs-btn-group-vertical>.bk-bs-btn:hover,.bk-bs-btn-group>.bk-bs-btn:focus,.bk-bs-btn-group-vertical>.bk-bs-btn:focus,.bk-bs-btn-group>.bk-bs-btn:active,.bk-bs-btn-group-vertical>.bk-bs-btn:active,.bk-bs-btn-group>.bk-bs-btn.bk-bs-active,.bk-bs-btn-group-vertical>.bk-bs-btn.bk-bs-active{z-index:2}.bk-bs-btn-group>.bk-bs-btn:focus,.bk-bs-btn-group-vertical>.bk-bs-btn:focus{outline:0}.bk-bs-btn-group .bk-bs-btn+.bk-bs-btn,.bk-bs-btn-group .bk-bs-btn+.bk-bs-btn-group,.bk-bs-btn-group .bk-bs-btn-group+.bk-bs-btn,.bk-bs-btn-group .bk-bs-btn-group+.bk-bs-btn-group{margin-left:-1px}.bk-bs-btn-toolbar{margin-left:-5px}.bk-bs-btn-toolbar .bk-bs-btn-group,.bk-bs-btn-toolbar .bk-bs-input-group{float:left}.bk-bs-btn-toolbar>.bk-bs-btn,.bk-bs-btn-toolbar>.bk-bs-btn-group,.bk-bs-btn-toolbar>.bk-bs-input-group{margin-left:5px}.bk-bs-btn-group>.bk-bs-btn:not(:first-child):not(:last-child):not(.bk-bs-dropdown-toggle){border-radius:0}.bk-bs-btn-group>.bk-bs-btn:first-child{margin-left:0}.bk-bs-btn-group>.bk-bs-btn:first-child:not(:last-child):not(.bk-bs-dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.bk-bs-btn-group>.bk-bs-btn:last-child:not(:first-child),.bk-bs-btn-group>.bk-bs-dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.bk-bs-btn-group>.bk-bs-btn-group{float:left}.bk-bs-btn-group>.bk-bs-btn-group:not(:first-child):not(:last-child)>.bk-bs-btn{border-radius:0}.bk-bs-btn-group>.bk-bs-btn-group:first-child>.bk-bs-btn:last-child,.bk-bs-btn-group>.bk-bs-btn-group:first-child>.bk-bs-dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.bk-bs-btn-group>.bk-bs-btn-group:last-child>.bk-bs-btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.bk-bs-btn-group .bk-bs-dropdown-toggle:active,.bk-bs-btn-group.bk-bs-open .bk-bs-dropdown-toggle{outline:0}.bk-bs-btn-group>.bk-bs-btn+.bk-bs-dropdown-toggle{padding-left:8px;padding-right:8px}.bk-bs-btn-group>.bk-bs-btn-lg+.bk-bs-dropdown-toggle{padding-left:12px;padding-right:12px}.bk-bs-btn-group.bk-bs-open .bk-bs-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)}.bk-bs-btn-group.bk-bs-open .bk-bs-dropdown-toggle.bk-bs-btn-link{-webkit-box-shadow:none;box-shadow:none}.bk-bs-btn .bk-bs-caret{margin-left:0}.bk-bs-btn-lg .bk-bs-caret{border-width:5px 5px 0;border-bottom-width:0}.bk-bs-dropup .bk-bs-btn-lg .bk-bs-caret{border-width:0 5px 5px}.bk-bs-btn-group-vertical>.bk-bs-btn,.bk-bs-btn-group-vertical>.bk-bs-btn-group,.bk-bs-btn-group-vertical>.bk-bs-btn-group>.bk-bs-btn{display:block;float:none;width:100%;max-width:100%}.bk-bs-btn-group-vertical>.bk-bs-btn-group>.bk-bs-btn{float:none}.bk-bs-btn-group-vertical>.bk-bs-btn+.bk-bs-btn,.bk-bs-btn-group-vertical>.bk-bs-btn+.bk-bs-btn-group,.bk-bs-btn-group-vertical>.bk-bs-btn-group+.bk-bs-btn,.bk-bs-btn-group-vertical>.bk-bs-btn-group+.bk-bs-btn-group{margin-top:-1px;margin-left:0}.bk-bs-btn-group-vertical>.bk-bs-btn:not(:first-child):not(:last-child){border-radius:0}.bk-bs-btn-group-vertical>.bk-bs-btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.bk-bs-btn-group-vertical>.bk-bs-btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.bk-bs-btn-group-vertical>.bk-bs-btn-group:not(:first-child):not(:last-child)>.bk-bs-btn{border-radius:0}.bk-bs-btn-group-vertical>.bk-bs-btn-group:first-child:not(:last-child)>.bk-bs-btn:last-child,.bk-bs-btn-group-vertical>.bk-bs-btn-group:first-child:not(:last-child)>.bk-bs-dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.bk-bs-btn-group-vertical>.bk-bs-btn-group:last-child:not(:first-child)>.bk-bs-btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.bk-bs-btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.bk-bs-btn-group-justified>.bk-bs-btn,.bk-bs-btn-group-justified>.bk-bs-btn-group{float:none;display:table-cell;width:1%}.bk-bs-btn-group-justified>.bk-bs-btn-group .bk-bs-btn{width:100%}[data-bk-bs-toggle="buttons"]>.bk-bs-btn>input[type="radio"],[data-bk-bs-toggle="buttons"]>.bk-bs-btn>input[type="checkbox"]{display:none}.bk-bs-input-group{position:relative;display:table;border-collapse:separate}.bk-bs-input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.bk-bs-input-group .bk-bs-form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.bk-bs-input-group-lg>.bk-bs-form-control,.bk-bs-input-group-lg>.bk-bs-input-group-addon,.bk-bs-input-group-lg>.bk-bs-input-group-btn>.bk-bs-btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.bk-bs-input-group-lg>.bk-bs-form-control,select.bk-bs-input-group-lg>.bk-bs-input-group-addon,select.bk-bs-input-group-lg>.bk-bs-input-group-btn>.bk-bs-btn{height:46px;line-height:46px}textarea.bk-bs-input-group-lg>.bk-bs-form-control,textarea.bk-bs-input-group-lg>.bk-bs-input-group-addon,textarea.bk-bs-input-group-lg>.bk-bs-input-group-btn>.bk-bs-btn,select[multiple].bk-bs-input-group-lg>.bk-bs-form-control,select[multiple].bk-bs-input-group-lg>.bk-bs-input-group-addon,select[multiple].bk-bs-input-group-lg>.bk-bs-input-group-btn>.bk-bs-btn{height:auto}.bk-bs-input-group-sm>.bk-bs-form-control,.bk-bs-input-group-sm>.bk-bs-input-group-addon,.bk-bs-input-group-sm>.bk-bs-input-group-btn>.bk-bs-btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.bk-bs-input-group-sm>.bk-bs-form-control,select.bk-bs-input-group-sm>.bk-bs-input-group-addon,select.bk-bs-input-group-sm>.bk-bs-input-group-btn>.bk-bs-btn{height:30px;line-height:30px}textarea.bk-bs-input-group-sm>.bk-bs-form-control,textarea.bk-bs-input-group-sm>.bk-bs-input-group-addon,textarea.bk-bs-input-group-sm>.bk-bs-input-group-btn>.bk-bs-btn,select[multiple].bk-bs-input-group-sm>.bk-bs-form-control,select[multiple].bk-bs-input-group-sm>.bk-bs-input-group-addon,select[multiple].bk-bs-input-group-sm>.bk-bs-input-group-btn>.bk-bs-btn{height:auto}.bk-bs-input-group-addon,.bk-bs-input-group-btn,.bk-bs-input-group .bk-bs-form-control{display:table-cell}.bk-bs-input-group-addon:not(:first-child):not(:last-child),.bk-bs-input-group-btn:not(:first-child):not(:last-child),.bk-bs-input-group .bk-bs-form-control:not(:first-child):not(:last-child){border-radius:0}.bk-bs-input-group-addon,.bk-bs-input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.bk-bs-input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.bk-bs-input-group-addon.bk-bs-input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.bk-bs-input-group-addon.bk-bs-input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.bk-bs-input-group-addon input[type="radio"],.bk-bs-input-group-addon input[type="checkbox"]{margin-top:0}.bk-bs-input-group .bk-bs-form-control:first-child,.bk-bs-input-group-addon:first-child,.bk-bs-input-group-btn:first-child>.bk-bs-btn,.bk-bs-input-group-btn:first-child>.bk-bs-btn-group>.bk-bs-btn,.bk-bs-input-group-btn:first-child>.bk-bs-dropdown-toggle,.bk-bs-input-group-btn:last-child>.bk-bs-btn:not(:last-child):not(.bk-bs-dropdown-toggle),.bk-bs-input-group-btn:last-child>.bk-bs-btn-group:not(:last-child)>.bk-bs-btn{border-bottom-right-radius:0;border-top-right-radius:0}.bk-bs-input-group-addon:first-child{border-right:0}.bk-bs-input-group .bk-bs-form-control:last-child,.bk-bs-input-group-addon:last-child,.bk-bs-input-group-btn:last-child>.bk-bs-btn,.bk-bs-input-group-btn:last-child>.bk-bs-btn-group>.bk-bs-btn,.bk-bs-input-group-btn:last-child>.bk-bs-dropdown-toggle,.bk-bs-input-group-btn:first-child>.bk-bs-btn:not(:first-child),.bk-bs-input-group-btn:first-child>.bk-bs-btn-group:not(:first-child)>.bk-bs-btn{border-bottom-left-radius:0;border-top-left-radius:0}.bk-bs-input-group-addon:last-child{border-left:0}.bk-bs-input-group-btn{position:relative;font-size:0;white-space:nowrap}.bk-bs-input-group-btn>.bk-bs-btn{position:relative}.bk-bs-input-group-btn>.bk-bs-btn+.bk-bs-btn{margin-left:-1px}.bk-bs-input-group-btn>.bk-bs-btn:hover,.bk-bs-input-group-btn>.bk-bs-btn:focus,.bk-bs-input-group-btn>.bk-bs-btn:active{z-index:2}.bk-bs-input-group-btn:first-child>.bk-bs-btn,.bk-bs-input-group-btn:first-child>.bk-bs-btn-group{margin-right:-1px}.bk-bs-input-group-btn:last-child>.bk-bs-btn,.bk-bs-input-group-btn:last-child>.bk-bs-btn-group{margin-left:-1px}.bk-bs-nav{margin-bottom:0;padding-left:0;list-style:none}.bk-bs-nav>li{position:relative;display:block}.bk-bs-nav>li>a{position:relative;display:block;padding:10px 15px}.bk-bs-nav>li>a:hover,.bk-bs-nav>li>a:focus{text-decoration:none;background-color:#eee}.bk-bs-nav>li.bk-bs-disabled>a{color:#999}.bk-bs-nav>li.bk-bs-disabled>a:hover,.bk-bs-nav>li.bk-bs-disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.bk-bs-nav .bk-bs-open>a,.bk-bs-nav .bk-bs-open>a:hover,.bk-bs-nav .bk-bs-open>a:focus{background-color:#eee;border-color:#428bca}.bk-bs-nav .bk-bs-nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.bk-bs-nav>li>a>img{max-width:none}.bk-bs-nav-tabs{border-bottom:1px solid #ddd}.bk-bs-nav-tabs>li{float:left;margin-bottom:-1px}.bk-bs-nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.bk-bs-nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.bk-bs-nav-tabs>li.bk-bs-active>a,.bk-bs-nav-tabs>li.bk-bs-active>a:hover,.bk-bs-nav-tabs>li.bk-bs-active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.bk-bs-nav-tabs.bk-bs-nav-justified{width:100%;border-bottom:0}.bk-bs-nav-tabs.bk-bs-nav-justified>li{float:none}.bk-bs-nav-tabs.bk-bs-nav-justified>li>a{text-align:center;margin-bottom:5px}.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-dropdown .bk-bs-dropdown-menu{top:auto;left:auto}@media(min-width:768px){.bk-bs-nav-tabs.bk-bs-nav-justified>li{display:table-cell;width:1%}.bk-bs-nav-tabs.bk-bs-nav-justified>li>a{margin-bottom:0}}.bk-bs-nav-tabs.bk-bs-nav-justified>li>a{margin-right:0;border-radius:4px}.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a,.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a:hover,.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a:focus{border:1px solid #ddd}@media(min-width:768px){.bk-bs-nav-tabs.bk-bs-nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a,.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a:hover,.bk-bs-nav-tabs.bk-bs-nav-justified>.bk-bs-active>a:focus{border-bottom-color:#fff}}.bk-bs-nav-pills>li{float:left}.bk-bs-nav-pills>li>a{border-radius:4px}.bk-bs-nav-pills>li+li{margin-left:2px}.bk-bs-nav-pills>li.bk-bs-active>a,.bk-bs-nav-pills>li.bk-bs-active>a:hover,.bk-bs-nav-pills>li.bk-bs-active>a:focus{color:#fff;background-color:#428bca}.bk-bs-nav-stacked>li{float:none}.bk-bs-nav-stacked>li+li{margin-top:2px;margin-left:0}.bk-bs-nav-justified{width:100%}.bk-bs-nav-justified>li{float:none}.bk-bs-nav-justified>li>a{text-align:center;margin-bottom:5px}.bk-bs-nav-justified>.bk-bs-dropdown .bk-bs-dropdown-menu{top:auto;left:auto}@media(min-width:768px){.bk-bs-nav-justified>li{display:table-cell;width:1%}.bk-bs-nav-justified>li>a{margin-bottom:0}}.bk-bs-nav-tabs-justified{border-bottom:0}.bk-bs-nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.bk-bs-nav-tabs-justified>.bk-bs-active>a,.bk-bs-nav-tabs-justified>.bk-bs-active>a:hover,.bk-bs-nav-tabs-justified>.bk-bs-active>a:focus{border:1px solid #ddd}@media(min-width:768px){.bk-bs-nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.bk-bs-nav-tabs-justified>.bk-bs-active>a,.bk-bs-nav-tabs-justified>.bk-bs-active>a:hover,.bk-bs-nav-tabs-justified>.bk-bs-active>a:focus{border-bottom-color:#fff}}.bk-bs-tab-content>.bk-bs-tab-pane{display:none}.bk-bs-tab-content>.bk-bs-active{display:block}.bk-bs-nav-tabs .bk-bs-dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.bk-bs-label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.bk-bs-label[href]:hover,.bk-bs-label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.bk-bs-label:empty{display:none}.bk-bs-btn .bk-bs-label{position:relative;top:-1px}.bk-bs-label-default{background-color:#999}.bk-bs-label-default[href]:hover,.bk-bs-label-default[href]:focus{background-color:gray}.bk-bs-label-primary{background-color:#428bca}.bk-bs-label-primary[href]:hover,.bk-bs-label-primary[href]:focus{background-color:#3071a9}.bk-bs-label-success{background-color:#5cb85c}.bk-bs-label-success[href]:hover,.bk-bs-label-success[href]:focus{background-color:#449d44}.bk-bs-label-info{background-color:#5bc0de}.bk-bs-label-info[href]:hover,.bk-bs-label-info[href]:focus{background-color:#31b0d5}.bk-bs-label-warning{background-color:#f0ad4e}.bk-bs-label-warning[href]:hover,.bk-bs-label-warning[href]:focus{background-color:#ec971f}.bk-bs-label-danger{background-color:#d9534f}.bk-bs-label-danger[href]:hover,.bk-bs-label-danger[href]:focus{background-color:#c9302c}.bk-bs-panel{margin-bottom:20px;background-color:#fff;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)}.bk-bs-panel-body{padding:15px}.bk-bs-panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.bk-bs-panel-heading>.bk-bs-dropdown .bk-bs-dropdown-toggle{color:inherit}.bk-bs-panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.bk-bs-panel-title>a{color:inherit}.bk-bs-panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.bk-bs-panel>.bk-bs-list-group{margin-bottom:0}.bk-bs-panel>.bk-bs-list-group .bk-bs-list-group-item{border-width:1px 0;border-radius:0}.bk-bs-panel>.bk-bs-list-group:first-child .bk-bs-list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.bk-bs-panel>.bk-bs-list-group:last-child .bk-bs-list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.bk-bs-panel-heading+.bk-bs-list-group .bk-bs-list-group-item:first-child{border-top-width:0}.bk-bs-panel>.bk-bs-table,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table{margin-bottom:0}.bk-bs-panel>.bk-bs-table:first-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.bk-bs-panel>.bk-bs-table:first-child>thead:first-child>tr:first-child td:first-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>thead:first-child>tr:first-child td:first-child,.bk-bs-panel>.bk-bs-table:first-child>tbody:first-child>tr:first-child td:first-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>tbody:first-child>tr:first-child td:first-child,.bk-bs-panel>.bk-bs-table:first-child>thead:first-child>tr:first-child th:first-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>thead:first-child>tr:first-child th:first-child,.bk-bs-panel>.bk-bs-table:first-child>tbody:first-child>tr:first-child th:first-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.bk-bs-panel>.bk-bs-table:first-child>thead:first-child>tr:first-child td:last-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>thead:first-child>tr:first-child td:last-child,.bk-bs-panel>.bk-bs-table:first-child>tbody:first-child>tr:first-child td:last-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>tbody:first-child>tr:first-child td:last-child,.bk-bs-panel>.bk-bs-table:first-child>thead:first-child>tr:first-child th:last-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>thead:first-child>tr:first-child th:last-child,.bk-bs-panel>.bk-bs-table:first-child>tbody:first-child>tr:first-child th:last-child,.bk-bs-panel>.bk-bs-table-responsive:first-child>.bk-bs-table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.bk-bs-panel>.bk-bs-table:last-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.bk-bs-panel>.bk-bs-table:last-child>tbody:last-child>tr:last-child td:first-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tbody:last-child>tr:last-child td:first-child,.bk-bs-panel>.bk-bs-table:last-child>tfoot:last-child>tr:last-child td:first-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tfoot:last-child>tr:last-child td:first-child,.bk-bs-panel>.bk-bs-table:last-child>tbody:last-child>tr:last-child th:first-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tbody:last-child>tr:last-child th:first-child,.bk-bs-panel>.bk-bs-table:last-child>tfoot:last-child>tr:last-child th:first-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.bk-bs-panel>.bk-bs-table:last-child>tbody:last-child>tr:last-child td:last-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tbody:last-child>tr:last-child td:last-child,.bk-bs-panel>.bk-bs-table:last-child>tfoot:last-child>tr:last-child td:last-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tfoot:last-child>tr:last-child td:last-child,.bk-bs-panel>.bk-bs-table:last-child>tbody:last-child>tr:last-child th:last-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tbody:last-child>tr:last-child th:last-child,.bk-bs-panel>.bk-bs-table:last-child>tfoot:last-child>tr:last-child th:last-child,.bk-bs-panel>.bk-bs-table-responsive:last-child>.bk-bs-table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.bk-bs-panel>.bk-bs-panel-body+.bk-bs-table,.bk-bs-panel>.bk-bs-panel-body+.bk-bs-table-responsive{border-top:1px solid #ddd}.bk-bs-panel>.bk-bs-table>tbody:first-child>tr:first-child th,.bk-bs-panel>.bk-bs-table>tbody:first-child>tr:first-child td{border-top:0}.bk-bs-panel>.bk-bs-table-bordered,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered{border:0}.bk-bs-panel>.bk-bs-table-bordered>thead>tr>th:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>th:first-child,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr>th:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>th:first-child,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr>th:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>th:first-child,.bk-bs-panel>.bk-bs-table-bordered>thead>tr>td:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>td:first-child,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr>td:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>td:first-child,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr>td:first-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>td:first-child{border-left:0}.bk-bs-panel>.bk-bs-table-bordered>thead>tr>th:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>th:last-child,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr>th:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>th:last-child,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr>th:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>th:last-child,.bk-bs-panel>.bk-bs-table-bordered>thead>tr>td:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr>td:last-child,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr>td:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr>td:last-child,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr>td:last-child,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr>td:last-child{border-right:0}.bk-bs-panel>.bk-bs-table-bordered>thead>tr:first-child>td,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr:first-child>td,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr:first-child>td,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:first-child>td,.bk-bs-panel>.bk-bs-table-bordered>thead>tr:first-child>th,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>thead>tr:first-child>th,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr:first-child>th,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:first-child>th{border-bottom:0}.bk-bs-panel>.bk-bs-table-bordered>tbody>tr:last-child>td,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:last-child>td,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr:last-child>td,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr:last-child>td,.bk-bs-panel>.bk-bs-table-bordered>tbody>tr:last-child>th,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tbody>tr:last-child>th,.bk-bs-panel>.bk-bs-table-bordered>tfoot>tr:last-child>th,.bk-bs-panel>.bk-bs-table-responsive>.bk-bs-table-bordered>tfoot>tr:last-child>th{border-bottom:0}.bk-bs-panel>.bk-bs-table-responsive{border:0;margin-bottom:0}.bk-bs-panel-group{margin-bottom:20px}.bk-bs-panel-group .bk-bs-panel{margin-bottom:0;border-radius:4px;overflow:hidden}.bk-bs-panel-group .bk-bs-panel+.bk-bs-panel{margin-top:5px}.bk-bs-panel-group .bk-bs-panel-heading{border-bottom:0}.bk-bs-panel-group .bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top:1px solid #ddd}.bk-bs-panel-group .bk-bs-panel-footer{border-top:0}.bk-bs-panel-group .bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom:1px solid #ddd}.bk-bs-panel-default{border-color:#ddd}.bk-bs-panel-default>.bk-bs-panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.bk-bs-panel-default>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#ddd}.bk-bs-panel-default>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#ddd}.bk-bs-panel-primary{border-color:#428bca}.bk-bs-panel-primary>.bk-bs-panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.bk-bs-panel-primary>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#428bca}.bk-bs-panel-primary>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#428bca}.bk-bs-panel-success{border-color:#d6e9c6}.bk-bs-panel-success>.bk-bs-panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.bk-bs-panel-success>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#d6e9c6}.bk-bs-panel-success>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#d6e9c6}.bk-bs-panel-info{border-color:#bce8f1}.bk-bs-panel-info>.bk-bs-panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.bk-bs-panel-info>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#bce8f1}.bk-bs-panel-info>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#bce8f1}.bk-bs-panel-warning{border-color:#faebcc}.bk-bs-panel-warning>.bk-bs-panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.bk-bs-panel-warning>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#faebcc}.bk-bs-panel-warning>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#faebcc}.bk-bs-panel-danger{border-color:#ebccd1}.bk-bs-panel-danger>.bk-bs-panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.bk-bs-panel-danger>.bk-bs-panel-heading+.bk-bs-panel-collapse .bk-bs-panel-body{border-top-color:#ebccd1}.bk-bs-panel-danger>.bk-bs-panel-footer+.bk-bs-panel-collapse .bk-bs-panel-body{border-bottom-color:#ebccd1}.bk-bs-close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.bk-bs-close:hover,.bk-bs-close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.bk-bs-close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.bk-bs-modal-open{overflow:hidden}.bk-bs-modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.bk-bs-modal.bk-bs-fade .bk-bs-modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.bk-bs-modal.bk-bs-in .bk-bs-modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.bk-bs-modal-dialog{position:relative;width:auto;margin:10px}.bk-bs-modal-content{position:relative;background-color:#fff;border:1px solid #999;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);background-clip:padding-box;outline:0}.bk-bs-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.bk-bs-modal-backdrop.bk-bs-fade{opacity:0;filter:alpha(opacity=0)}.bk-bs-modal-backdrop.bk-bs-in{opacity:.5;filter:alpha(opacity=50)}.bk-bs-modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.bk-bs-modal-header .bk-bs-close{margin-top:-2px}.bk-bs-modal-title{margin:0;line-height:1.42857143}.bk-bs-modal-body{position:relative;padding:20px}.bk-bs-modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.bk-bs-modal-footer .bk-bs-btn+.bk-bs-btn{margin-left:5px;margin-bottom:0}.bk-bs-modal-footer .bk-bs-btn-group .bk-bs-btn+.bk-bs-btn{margin-left:-1px}.bk-bs-modal-footer .bk-bs-btn-block+.bk-bs-btn-block{margin-left:0}@media(min-width:768px){.bk-bs-modal-dialog{width:600px;margin:30px auto}.bk-bs-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)}.bk-bs-modal-sm{width:300px}}@media(min-width:992px){.bk-bs-modal-lg{width:900px}}.bk-bs-clearfix:before,.bk-bs-clearfix:after,.bk-bs-container:before,.bk-bs-container:after,.bk-bs-container-fluid:before,.bk-bs-container-fluid:after,.bk-bs-row:before,.bk-bs-row:after,.bk-bs-form-horizontal .bk-bs-form-group:before,.bk-bs-form-horizontal .bk-bs-form-group:after,.bk-bs-btn-toolbar:before,.bk-bs-btn-toolbar:after,.bk-bs-btn-group-vertical>.bk-bs-btn-group:before,.bk-bs-btn-group-vertical>.bk-bs-btn-group:after,.bk-bs-nav:before,.bk-bs-nav:after,.bk-bs-panel-body:before,.bk-bs-panel-body:after,.bk-bs-modal-footer:before,.bk-bs-modal-footer:after{content:" ";display:table}.bk-bs-clearfix:after,.bk-bs-container:after,.bk-bs-container-fluid:after,.bk-bs-row:after,.bk-bs-form-horizontal .bk-bs-form-group:after,.bk-bs-btn-toolbar:after,.bk-bs-btn-group-vertical>.bk-bs-btn-group:after,.bk-bs-nav:after,.bk-bs-panel-body:after,.bk-bs-modal-footer:after{clear:both}.bk-bs-center-block{display:block;margin-left:auto;margin-right:auto}.bk-bs-pull-right{float:right !important}.bk-bs-pull-left{float:left !important}.bk-bs-hide{display:none !important}.bk-bs-show{display:block !important}.bk-bs-invisible{visibility:hidden}.bk-bs-text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.bk-bs-hidden{display:none !important;visibility:hidden !important}.bk-bs-affix{position:fixed}.tableelem{padding:2px 10px;border:2px white;background-color:#e0e0e0}.tableheader{background-color:silver}#notebook .bk-plot-wrapper table{border:none !important}#notebook .bk-plot-wrapper table tr{border:none !important}#notebook .bk-plot-wrapper table tr td{border:none !important;padding:0 !important;margin:0 !important}#notebook .bk-plot-wrapper table tr td.bk-plot-above{border-bottom:2px solid #efefef !important}#notebook .bk-plot-wrapper table tr td.bk-plot-below{border-top:2px solid #efefef !important}#notebook .bk-plot-wrapper table tr td.bk-plot-left{border-right:2px solid #efefef !important}#notebook .bk-plot-wrapper table tr td.bk-plot-right{border-left:2px solid #efefef !important}.bk-table table tr td{padding:2px}.bk-table form table tr td{padding:2px}.bk-table form table tr td input{padding:0}.jsp:after,.bk-plot:after,.bk-canvas-wrapper:after,.bk-sidebar:after,.bk-box:after{content:" ";height:0;display:block;clear:both}.bk-canvas-wrapper .bk-resize-popup{position:absolute;left:0;top:0;width:40px;height:40px;overflow:hidden;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAEnSURBVEiJzZXBioQwDIb/XQuF6U3wCRSEvv8zeFOoB2++QD14aqHSOntYtthxdHesDptTk4Z+hKR/PqqquuNi+7wa8DYIWTplWSJN0yDBGAMhBJxzhyFBJY8AACCErGKv2u4L1lp0XRdVBfBLTwghuN1uUYBNiDHGn4uiQJZl50GmaYJSCm3bou/700BBT4QQAL57IaUEAOR57kEAMAxDHMRaG1wuQc45aK1fBqwgz+wHpJSCUuoayBJ01P6/djHG/jR1hzWDMQbOuZedvak7XAljzAMe/xGlFEmSeP9wJVv/SGsNzjmcc2iaJg6yBbLWghASqHf0dEkpAwl6thpOGWGl1O46iIZQSsE5Dxp9OsQ5h3meV/FxHP05erdaa1HX9W7OW2TlC31ceRWbb5+AAAAAAElFTkSuQmCC);background-position:bottom right;background-repeat:no-repeat;cursor:se-resize}.bk-canvas-wrapper:hover .bk-resize-popup{display:block}.bk-sidebar.bk-logo{margin:5px auto}.bk-logo{position:relative;display:block;background-repeat:no-repeat}.bk-logo.grey{filter:url("data:image/svg+xml;utf8,<svgxmlns=\'http://www.w3.org/2000/svg\'><filterid=\'grayscale\'><feColorMatrixtype=\'matrix\'values=\'0.33330.33330.3333000.33330.33330.3333000.33330.33330.33330000010\'/></filter></svg>#grayscale");filter:gray;-webkit-filter:grayscale(100%)}.bk-logo-notebook{display:inline-block;vertical-align:middle;margin-right:5px}.bk-banner>span{display:inline-block;vertical-align:middle}.bk-logo-small{width:20px;height:20px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAOkSURBVDiNjZRtaJVlGMd/1/08zzln5zjP1LWcU9N0NkN8m2CYjpgQYQXqSs0I84OLIC0hkEKoPtiH3gmKoiJDU7QpLgoLjLIQCpEsNJ1vqUOdO7ppbuec5+V+rj4ctwzd8IIbbi6u+8f1539dt3A78eXC7QizUF7gyV1fD1Yqg4JWz84yffhm0qkFqBogB9rM8tZdtwVsPUhWhGcFJngGeWrPzHm5oaMmkfEg1usvLFyc8jLRqDOMru7AyC8saQr7GG7f5fvDeH7Ej8CM66nIF+8yngt6HWaKh7k49Soy9nXurCi1o3qUbS3zWfrYeQDTB/Qj6kX6Ybhw4B+bOYoLKCC9H3Nu/leUTZ1JdRWkkn2ldcCamzrcf47KKXdAJllSlxAOkRgyHsGC/zRday5Qld9DyoM4/q/rUoy/CXh3jzOu3bHUVZeU+DEn8FInkPBFlu3+nW3Nw0mk6vCDiWg8CeJaxEwuHS3+z5RgY+YBR6V1Z1nxSOfoaPa4LASWxxdNp+VWTk7+4vzaou8v8PN+xo+KY2xsw6une2frhw05CTYOmQvsEhjhWjn0bmXPjpE1+kplmmkP3suftwTubK9Vq22qKmrBhpY4jvd5afdRA3wGjFAgcnTK2s4hY0/GPNIb0nErGMCRxWOOX64Z8RAC4oCXdklmEvcL8o0BfkNK4lUg9HTl+oPlQxdNo3Mg4Nv175e/1LDGzZen30MEjRUtmXSfiTVu1kK8W4txyV6BMKlbgk3lMwYCiusNy9fVfvvwMxv8Ynl6vxoByANLTWplvuj/nF9m2+PDtt1eiHPBr1oIfhCChQMBw6Aw0UulqTKZdfVvfG7VcfIqLG9bcldL/+pdWTLxLUy8Qq38heUIjh4XlzZxzQm19lLFlr8vdQ97rjZVOLf8nclzckbcD4wxXMidpX30sFd37Fv/GtwwhzhxGVAprjbg0gCAEeIgwCZyTV2Z1REEW8O4py0wsjeloKoMr6iCY6dP92H6Vw/oTyICIthibxjm/DfN9lVz8IqtqKYLUXfoKVMVQVVJOElGjrnnUt9T9wbgp8AyYKaGlqingHZU/uG2NTZSVqwHQTWkx9hxjkpWDaCg6Ckj5qebgBVbT3V3NNXMSiWSDdGV3hrtzla7J+duwPOToIg42ChPQOQjspnSlp1V+Gjdged7+8UN5CRAV7a5EdFNwCjEaBR27b3W890TE7g24NAP/mMDXRWrGoFPQI9ls/MWO2dWFAar/xcOIImbbpA3zgAAAABJRU5ErkJggg==)}.bk-logo-medium{width:35px;height:35px;background-image:url(data:image/png;base64,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)}.bk-logo-large{width:75px;height:75px;background-image:url(data:image/png;base64,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)}.bk-sidebar{box-sizing:border-box}.bk-button-bar .bk-bs-dropdown{padding:10px 10px 0 5px}.bk-button-bar .bk-bs-dropdown a{color:transparent;font-size:0;display:block;float:left;width:13px;height:13px;margin:5px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAGdSURBVCiRXZJPSxtRFMV/dyYTunBREASRIkKwddPSjYIL+x2K9plR+owR7K7L7vsZutIkZqhO8jZ+h25aQilUkbaUgv2zEOpGpAsZnbld+BJC7ubAvYd77uEeYaTaB25bhJqi44Kcq9LYWDOt/lxVkQG542ZFaQP3gB6wBLwDFoGfKtQ2qua7qhIAJB1XEeUE9CtSPLCxWQbObGxWEL0P+k2Uk3barQBImrrgWvmE8NnGpgaQpO4OcArM2Nhc+d4e8DCUcL6UwZYIk0WYzw9Zy4CnHm+9hNcvJI/+3GhuJUndR+A3yCpoCGQ2NkWfnKQuAMqo5Ih2gakScBeYBj32vE3gw5DqAtBCFGAcuCwBF8CRIFX1SiNf6AGPQXLwSgq7Aq+zMGPLrPdNB16h50+92uvul4MiWlJ4FZShAZxFebQztL0MHHoEICiiBvCrRJiI31wBvii8zQt9WV9f/Zek7sjG5lFzvzsWBvJGYA2Ye1599mOQiKTjZlVpCcwA74En/UQonIqwaX0ihJFKUlcH6sAE8Bdo2tg0B/9S5T8JNaZ11wlT0wAAAABJRU5ErkJggg==)}.bk-button-bar .bk-button-bar-list{margin:0;padding:0}.bk-button-bar-list>li{list-style-type:none;float:left;padding:0;margin:0;position:relative;display:block;overflow:visible;background-color:transparent}.bk-button-bar-list>li:last-child:after{content:"|";font-size:90%;color:lightgray;display:inline-block;float:left;height:28px;line-height:28px;padding:0 3px}.bk-button-bar-list.bk-bs-dropdown:after{content:"|";font-size:90%;color:lightgray;display:inline-block;float:left;height:28px;line-height:28px;padding:0 3px}.bk-button-bar-list[type='help'] li:after{content:"" !important;display:none}.bk-button-bar-list>a:after{content:"|";font-size:90%;color:lightgray;display:inline-block;float:left;height:28px;line-height:28px;padding:0 3px}.bk-button-bar .bk-button-bar-list .bk-bs-dropdown-menu{padding:10px 8px}.bk-button-bar .bk-button-bar-list .bk-bs-dropdown-menu li{float:none;clear:both;font-family:Helvetica,sans-serif;line-height:1.5em}.bk-button-bar .bk-button-bar-list .bk-bs-dropdown-menu li input{margin-right:8px}.bk-button-bar-list .bk-toolbar-button{width:30px;height:28px;padding:5px;border:0;border-radius:0 !important;-moz-border-radius:0 !important;-webkit-border-radius:0 !important;background:transparent !important}.bk-button-bar-list .bk-toolbar-button .bk-btn-icon{display:block;position:relative;height:16px;margin:0;border:0;background-size:contain;background-color:transparent;background-repeat:no-repeat;background-position:center center}.bk-button-bar-list .bk-toolbar-button span.tip{display:none}.bk-button-bar-list .bk-toolbar-button span.tip:before{display:none;content:" ";position:relative;width:100%;background-position:top left;background-repeat:no-repeat}.bk-button-bar-list li::hover .bk-toolbar-button{cursor:pointer;background:transparent !important}.bk-button-bar-list li:hover .bk-toolbar-button span.tip:before{display:inline-block}.bk-button-bar-list li:hover .bk-toolbar-button span.tip{z-index:100;font-size:100%;color:#fff;font-family:'Open Sans',sans-serif;white-space:nowrap;background-color:#818789;border-radius:3px !important;-moz-border-radius:3px !important;-webkit-border-radius:3px !important;display:inline-block;position:relative;top:25px;padding:3px 5px;transition:all .6s ease;-webkit-transition:all .6s ease;-moz-transition:all .6s ease;-o-transition:all .6s ease}.bk-button-bar-list li:hover .bk-toolbar-button span.tip>*{display:block;text-align:left}.bk-button-bar-list li:hover .bk-toolbar-button span.tip span{width:200px;white-space:normal}.bk-button-bar-list .bk-toolbar-button.active{background:#fff;-box-shadow:none !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;outline:none !important;border-bottom:2px solid #26aae1}.bk-button-bar>.bk-toolbar-button.active{border-bottom:2px solid #26aae1}.bk-plot-above.bk-toolbar-active{border-bottom:2px solid #e5e5e5}.bk-plot-below.bk-toolbar-active{border-top:2px solid #e5e5e5;padding-bottom:45px}.bk-plot-above.bk-toolbar-active,.bk-plot-below.bk-toolbar-active{height:30px}.bk-plot-above.bk-toolbar-active .bk-logo,.bk-plot-below.bk-toolbar-active .bk-logo{float:left;top:5px;margin:5px 0}.bk-plot-above.bk-toolbar-active .bk-button-bar,.bk-plot-below.bk-toolbar-active .bk-button-bar{float:right;position:relative;top:5px}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-button-bar-list,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-button-bar-list{float:left}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown{margin-right:20px}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:before,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:before{right:-6px}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:after,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:after{right:-12px;position:absolute}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-button-bar-list .bk-bs-dropdown-menu:after,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-button-bar-list .bk-bs-dropdown-menu:after{content:""}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button{float:left}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help{float:right}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help span.tip,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help span.tip{right:0;text-align:left;width:200px;white-space:normal}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help span.tip>*,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button.help span.tip>*{margin-left:0;margin-right:0}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button span.tip,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button span.tip{top:41px;left:0;z-index:100;position:absolute;width:auto;padding:0 10px 5px 10px}.bk-plot-above.bk-toolbar-active .bk-button-bar .bk-toolbar-button span.tip:before,.bk-plot-below.bk-toolbar-active .bk-button-bar .bk-toolbar-button span.tip:before{top:-7px;left:-5px;width:100%;height:9px;padding:0 10px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAYAAAAGuM1UAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3NzIwRUFGMDYyMjE2ODExOTdBNUNBNjVEQTY5OTRDRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDQjA4MDBGRDQ3NjExMUU0QjI1NEVEQTlCODRBRDIyNiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDQjA4MDBGQzQ3NjExMUU0QjI1NEVEQTlCODRBRDIyNiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6N0Y0M0E0Nzk5NDIyNjgxMTk3QTVDQTY1REE2OTk0Q0UiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzcyMEVBRjA2MjIxNjgxMTk3QTVDQTY1REE2OTk0Q0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4te1g5AAAAk0lEQVR42mL8//8/AymApamjC5dcJRBPBOJvyIJM2FQCbS0GUm1APAddDkPDv3//3BgZGTuh3Eig5lKcGv78+aPKxMS0HMhkhokBNbcDDfHApoGHmZl5HZAWQrOUGWQIyDBkDYxAqxcBTdPBEQACQMM2AGk+Jqgn64CKA/EFJ1BeC2QoE9B9AUBOPTFxAFTnDxBgAI5eL2ABBdyaAAAAAElFTkSuQmCC);display:block !important}.bk-plot-left.bk-toolbar-active{border-right:2px solid #e5e5e5}.bk-plot-right.bk-toolbar-active{border-left:2px solid #e5e5e5}.bk-plot-left.bk-toolbar-active,.bk-plot-right.bk-toolbar-active{display:block;margin:45px 0 0 0}.bk-plot-left.bk-toolbar-active .bk-logo,.bk-plot-right.bk-toolbar-active .bk-logo{left:6px;margin-bottom:20px}.bk-plot-left.bk-toolbar-active .bk-button-bar,.bk-plot-right.bk-toolbar-active .bk-button-bar{position:relative;left:3px}.bk-plot-left.bk-toolbar-active .bk-button-bar:before,.bk-plot-right.bk-toolbar-active .bk-button-bar:before,.bk-plot-left.bk-toolbar-active .bk-button-bar:after,.bk-plot-right.bk-toolbar-active .bk-button-bar:after{content:" ";display:block;height:0;clear:both}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list:after,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list:after{content:" ";height:0;display:block;clear:both}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:before,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:before{top:}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:after,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list.bk-bs-dropdown:after{content:" \2014";float:none;clear:both;display:block;width:30px;height:8px;line-height:8px;padding:3px 0;text-align:center}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li{clear:both}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li:last-child:after,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li:last-child:after{content:" \2014";float:none;clear:both;display:block;width:30px;height:8px;line-height:8px;padding:3px 0;text-align:center}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button.active,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button.active{border-bottom:0;border-right:2px solid #26aae1}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button.help span.tip:before,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button.help span.tip:before{left:-57%}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button span.tip,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button span.tip{position:absolute;top:4px;left:40px;padding:5px 10px 5px 10px}.bk-plot-left.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button span.tip:before,.bk-plot-right.bk-toolbar-active .bk-button-bar .bk-button-bar-list>li .bk-toolbar-button span.tip:before{top:2px;left:-19px;width:9px;height:15px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAPCAMAAAABFhU/AAAAA3NCSVQICAjb4U/gAAAAY1BMVEX////////8/Pz5+fn39/f19fX09PTv8fHv7+/t7e7s7Ozp6enn6Onm5ubj4+Ph4eHf39/X2drW1tfMzMzAw8S+wMGusbKorK6orK2nq6ufo6WcoaGYnZ+RlpiJj5GGjI6Bh4n1ho2QAAAAIXRSTlMA//////////////////////////////////////////9G9E6kAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABR0RVh0Q3JlYXRpb24gVGltZQA5LzUvMTTY+fXxAAAAUklEQVQImTXN2xZAIABE0VQUIfdLwvz/V1rL1DztpzOi4EoIQoekNoIaH1AL8EvvoExEUkBWfWZZvyWVzq/vL6kbP9/sKdtPF8vKdMPBN1m5AR+0BAnD6uP50QAAAABJRU5ErkJggg==)}.bk-bs-caret{color:lightgray;display:inline-block;width:0;height:0;position:relative;left:11px;top:3px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.bk-hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:-ms-flexbox;display:box;box-orient:horizontal;box-align:stretch;display:flex;display:-webkit-flex;flex-direction:row;flex-wrap:nowrap}.bk-vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;width:auto}.bk-hbox-spacer{margin-right:40px}.bk-vbox-spacer{margin-bottom:auto}.bk-button-bar{margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:2px;position:relative;display:inline-block;vertical-align:middle}.bk-button-bar>.bk-bs-btn{position:relative;float:left}.bk-button-bar>.bk-bs-btn:hover,.bk-button-bar>.bk-bs-btn:focus,.bk-button-bar>.bk-bs-btn:active,.bk-button-bar>.bk-bs-btn.bk-bs-active{z-index:2}.bk-button-bar>.bk-bs-btn:focus{outline:0}.bk-button-bar .bk-bs-btn+.bk-bs-btn,.bk-button-bar .bk-bs-btn+.bk-bs-btn-group,.bk-button-bar .bk-bs-btn-group+.bk-bs-btn,.bk-button-bar .bk-bs-btn-group+.bk-bs-btn-group{margin-left:-1px}.bk-toolbar-button{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 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;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;color:#333;background-color:#fff;border-color:#ccc}.bk-toolbar-button:focus,.bk-toolbar-button:active:focus,.bk-toolbar-button.bk-bs-active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.bk-toolbar-button:hover,.bk-toolbar-button:focus{color:#333;text-decoration:none}.bk-toolbar-button:active,.bk-toolbar-button.bk-bs-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)}.bk-toolbar-button.bk-bs-disabled,.bk-toolbar-button[disabled],fieldset[disabled] .bk-toolbar-button{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.bk-toolbar-button:hover,.bk-toolbar-button:focus,.bk-toolbar-button:active,.bk-toolbar-button.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-toolbar-button{color:#333;background-color:#ebebeb;border-color:#adadad}.bk-toolbar-button:active,.bk-toolbar-button.bk-bs-active,.bk-bs-open .bk-bs-dropdown-toggle.bk-toolbar-button{background-image:none}.bk-toolbar-button.bk-bs-disabled,.bk-toolbar-button[disabled],fieldset[disabled] .bk-toolbar-button,.bk-toolbar-button.bk-bs-disabled:hover,.bk-toolbar-button[disabled]:hover,fieldset[disabled] .bk-toolbar-button:hover,.bk-toolbar-button.bk-bs-disabled:focus,.bk-toolbar-button[disabled]:focus,fieldset[disabled] .bk-toolbar-button:focus,.bk-toolbar-button.bk-bs-disabled:active,.bk-toolbar-button[disabled]:active,fieldset[disabled] .bk-toolbar-button:active,.bk-toolbar-button.bk-bs-disabled.bk-bs-active,.bk-toolbar-button[disabled].bk-bs-active,fieldset[disabled] .bk-toolbar-button.bk-bs-active{background-color:#fff;border-color:#ccc}.bk-toolbar-button .bk-bs-badge{color:#fff;background-color:#333}.bk-canvas-wrapper{position:relative;font-size:12pt;float:left}.bk-canvas{clear:both;position:absolute;font-size:12pt}.bk-canvas-wrapper .bk-canvas-map{position:absolute !important;z-index:-5}.bk-tooltip{position:absolute;padding:5px;border:1px solid #1e4b6c;background-color:#1e4b6c;border-radius:5px;pointer-events:none}.bk-tooltip.bk-left::before{position:absolute;margin:-7px 0 0 0;top:50%;width:0;height:0;border-style:solid;border-width:7px 0 7px 0;border-color:transparent;content:" ";display:block;left:-10px;border-right-width:10px;border-right-color:#1e4b6c}.bk-tooltip.bk-right::after{position:absolute;margin:-7px 0 0 0;top:50%;width:0;height:0;border-style:solid;border-width:7px 0 7px 0;border-color:transparent;content:" ";display:block;right:-10px;border-left-width:10px;border-left-color:#1e4b6c}.bk-tooltip.bk-tooltip-custom.bk-left::before{border-right-color:black}.bk-tooltip.bk-tooltip-custom.bk-right::after{border-left-color:black}.bk-tooltip.bk-tooltip-custom{border-color:black;background-color:white}.bk-tooltip-row-label{color:#9ab9b1;font-family:Helvetica,sans-serif;text-align:right}.bk-tooltip-row-value{color:#e2ddbd;font-family:Helvetica,sans-serif}.bk-tooltip-color-block{width:12px;height:12px;margin-left:5px;margin-right:5px;outline:#ddd solid 1px;display:inline-block}.bk-canvas-map{position:absolute;border:0;z-index:-5}.shading{position:absolute;display:block;border:1px dashed green;z-index:100}.gridplot_container{position:relative}.gridplot_container .gp_plotwrapper{position:absolute}.table_wrap table{display:block;margin:5px;height:300px;overflow-y:scroll}.bk-table{overflow:auto}.bokehdelete{float:right}.plottitle{padding-left:50px;padding-bottom:10px}.bk-toolbar-button.hover:focus{outline:0}.bk-tool-icon-box-select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAgCAYAAAB6kdqOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBODVDNDBCRjIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBODVDNDBDMDIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE4NUM0MEJEMjBCMzExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkE4NUM0MEJFMjBCMzExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+hdQ7dQAAAJdJREFUeNpiXLhs5X8GBPgIxAJQNjZxfiD+wIAKGCkUZ0SWZGIYZIAF3YVoPkEHH6kojhUMyhD6jydEaAlgaWnwh9BAgf9DKpfxDxYHjeay0Vw2bHMZw2guG81lwyXKRnMZWlt98JdDTFAX/x9NQwPkIH6kGMAVEyjyo7lstC4jouc69Moh9L42rlyBTZyYXDS00xBAgAEAqsguPe03+cYAAAAASUVORK5CYII=")}.bk-tool-icon-box-zoom{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAgCAYAAAB3j6rJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMjFERDhEMjIwQjIxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozMjFERDhEMzIwQjIxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjMyMUREOEQwMjBCMjExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjMyMUREOEQxMjBCMjExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+a2Q0KAAAAmVJREFUeNq8V19EpFEUvzOtmKfpJSJKDL2WiLJExKaUEq0eeikiaolZLT2lVUpPydqHqIlIo1ilFOmphxj1miKWWHppnobIt7+zeyZ3jjvz/bnf9OPHd8/9d77z3XN+94ts7ew6SqksWKX+w1GFiLjYdVSAfeAQ2Ag2sf0GvAXT4C/wle1x3lt9UOGBNk6BrYa+FuYIeAWOsmNviGqe6W+q081OmAGvizgh0cpjZ3RjGBFZBpMG+xn4wM8NYJfWFwNXwXrwS96RiIUTwwYn6AxMgb+FvQ5c4zOUxzR4Ce5GLZyo5LfSsQP2G5xQbKO+bWFfoLWinA1OAEcoM2rFRpMe5sloJWgtm4j0iPZcPhVdkOWxBWvZONIi2uc+5sqxbTaO1Ij2o4+5T6JdGy1SF4Kg2mLsi01E/oh2l4+5HTKaNlmTEe0ka40XyNqTsYnIkWiTwC16rMRNci0bR0hJ7w1veizqy9uB5D4ZDZKBtI3WvLCCJoT9E3jHny4j1DdmWOcbrWWjNYuGoqaL2kdmKayTztio7yzTJprz4A/9PuI3a8YMh5IKVC9fetxAY5rB79pNzXdESMJ/GrSjm8/DCTjAgpjQZCDDh5I+w4HuQBBHOsE9USty4KB2KF85m9J+v5XX9KXr3T7fQZS26WefYlcU+ayJlxhDIT40jBnn21hQOPrfgFtEqAhdGETqK7gZ4h/Av4g4Jf5TUoYquQSuqJDhFpEJca3b4EoYOtyyhrSkHTzlcj4R4t4FZ9NL+j6yMzlT/ocZES9aky3D3r6y5t2gaw3xWXgs7XFhdyzsgSpr2fFXgAEAmp2J9DuX/WgAAAAASUVORK5CYII=")}.bk-tool-icon-help{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBODVDNDBDMzIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBODVDNDBDNDIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE4NUM0MEMxMjBCMzExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkE4NUM0MEMyMjBCMzExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+mR+SmAAAA/BJREFUeNq8lulPU1kUwOnjCS2yL12pFZFRoBU1MYpCRVGD0cREo4kziX/ffDDxkzNmcEUUd0cBGYdhKYXSln0riyz+mNvceb6W15dxMvdDc3rfvb9z7rnn3HMsW1tbWTsPvkaisfFoND4xiTw9M8tkaUmxxWKxV5S7nE6304FsQLDspGB5ZeVDd89wKLz25YvB/pxdu/b6vA0Bv81qNatgY2PjY++nvs/96+vr/C0pLvJWetxOZ3Z2NrYzwzlYE4lGw6NjM7NzzKiqWnug5lB9HWsyKMDwRx2dk1PTyD5v5ZFDgcLCAoMTzM8vvP/YHQqPIpeXlZ4JNumO8o0CTIO+lEjk5+9ubjxRUV6WZW5MTE51POtiY57NdvZ0szioXgG2373XnlhedtgrWppP5ebkpLoukVguKMhPq2N1be3x02ex+AQ6LrWdl+dIKtjc3Lx3/yGecTrs51qCiqLInajs7ftjYHBY3nZRUeE+n++HmmqdEUDaHz1BB75qO3dWQJIK8GN3bx/WXTzfas3N1TrtweMODpdqMhcbPNVY6XZpJ1dWV3/57f7i4lKgvpb7Y0YRNhIzCE0njmvp6H7a9UJL1zqXGMPv7NUqYDsQBIDi07aCnk99rCZmdLdKis3NzQsZS3+6ce1y24Ufr1/1uJxSx+BQSHcyEhAUn8BuK0DqHxhCEifSDhJYyseOHhExjmeOHm6Q8zOzs6neEyiwwJXwWITwIHJS431pKSEEAkMbPDbbP5Ge9p0ABRAscDUWjzPlcblS151uOpk2IkMjo1IuKS5OuwYg4QRcEbluPqeGR8Kv372XD9H+6qq0ywQQuLqwsChC2wz9c//Ayzdvk46yWltbgqn5KHOFX+CqSB9syUgfCo28evtOerk12LxTVksgcDXL9CCfRVZysSSqNmMMhiJVZVzKQySdk5EuHaOIY/LqZlTAMyDzK+NiAQSuUE+QqIhZ/+kQQOCqw27/869BypO/7qDxnls3b5hXEPn7FQCueD1u3gCSwoyXTA5Q0VgcLHCeFnX/vr0E+O/dPTy/Bpf28+07Qt6dl3ftymUDBaD4ramuAr79mgbq65BI0anpme83n6oFCqC/rjb5XPOW0RMgdDzvovJ9D51Io4QgAASbVMCg4yC5yewnnc+pfP+OzkZKEBBQAPVFnw+/tj/AhJ2KvvGQRZ8cpO7KV+SbtoU7oG2h1PE5eLKxrLTEfNvS+eIlJuIWWiPtRqPGq8q353DAb/CiiXPTMHCrphov2f986OmlaiPwF3O8HsqwQ9c6jkdj4bExEXh84lYb/PWZW8f/o/nVBQa9RWR8HC/r2ndqltvlon3Xdmmp46sAAwDlJz2CuiavpwAAAABJRU5ErkJggg==")}.bk-tool-icon-inspector{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADEUlEQVRYR81XXVIaQRCeHqug8CXmBNETaE4gniDwIgpVspxAbxC9ATkBkCpQ8gKeQDiB5AQxNyAvUlrldr7eHxyGXZi1rMJ5opbp7m++7un+htSGF204vsoMoNXrlzSpfWa1oxQfhAegCZGaEtPorHo8znIoJwCt6+td8uk7ApUQCIHTF4BNAWzImq8ap6cP68CsBdDp9i9ZqXM7ML79g/EnCWD+jgMKENKqWT+tXK0CkQqgNRjs0OxpQIqKhoMxaG6/6JeRnK7T6yO2UvVqhYSlLX+ryORfgKn9ORDFIy7ky41yGcwsr0QAQfDH5zucOswx819fs4egI9OFCcD8DjBF7VNbEX0JzdWEt3NHSSASAcCxBDqMgt/623kvyTgNgNjJIfTjk4D4FqaJR1715MjmYAmA5Bx3AwUXQL+t105KaTlcBSC26XRvhjEIoLiq1yqXpr8FAGG16/ug4IT27fxBWu7EiQuAiImJpEMKE6nYM30uAIDDttSUOPfJP7JzbjPhAiBIh9QE67vIvoOi9WJfCwDavf40ulpjbCqmUf+W753ezURuh7Dg1SqflwAEHU6pgfyBq9Y4qx0LG++2fnZ/eUzcstmdM2AWH+jfc+liWdBJfSENf8Lifi3GVwC9mybOfi5dzatWVrbbLIHNva8p5h/16gkaFiLGGxbufkoE6XguwePiXLF3XmMfCUCUAqtKXU7sumd1CowOuJEi3Pg1FBpjitIGhyvVSfvmjci6ZR+rFQfDiPVE2jFYeICQ+PoewwjC5h7CZld6DBdyu6nDSKgzOyIMhmhK5TTqXYbRorZYM46TmpKAAOrGWwSJJekSB1yqJNOzp1Gs7YJ0EDeySDIMtJbQHh6Kf/uFfNFZkolJICRmz0P8DKWZuIG2g1hpok+Mk0Qphs0h9lzMtWRoNvYLuVImUWrmPJDlBKeRBDfATGOpHkhw670QSHWGLLckmF1PTsMlYqMJpyUbiO0weiMMceqLVTcotnMCYAYJJbcuQrVgZFP0NOOJYpr62pf3AmrHfWUG4O7abefGAfwH7EXSMJafOlYAAAAASUVORK5CYII=")}.bk-tool-icon-lasso-select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAgCAYAAAB6kdqOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3NzIwRUFGMDYyMjE2ODExOTdBNUNBNjVEQTY5OTRDRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1ODBEQzAzNDQ0RTMxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1ODBEQzAzMzQ0RTMxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTU0QzIwMUM1RjIxNjgxMUE3QkFFMzhGRjc2NTI3MjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzcyMEVBRjA2MjIxNjgxMTk3QTVDQTY1REE2OTk0Q0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7r0xDwAAAC9klEQVR42sSXb2hNcRjHz50rt1aslNQitSimq6VESW6SFMvFyJ+UknnhhVhkRIkX/iRbSPMnyt95sblZFvMC02patEKtaE3Km1taqWlxfZ/6Hj39+p17zr3nHJ76dO4953d+53ue5/k9v+ck2jseORHYRDAXpHmcDSar84McNwLegwHQa5soGULENFAPMmApH+5laXVcw9/fwA1wDYyFEbQI7FITl2vTQTPYDnaCj3KyooQJVoNu0BmBGG0zQc71YhAPzQEnGRY/+8R8+QGGVCjcXEqBZQy3tkrQBpYnfRL1EGgEEzzGSB48AT2gT+eCj8nLbQCbDU9lk0USto35Ytov0MWE7C8zTL3kKbiiFsQqWw7VcaBNzD2wGOwJIUabePeB+l9tCloI2i0xlnCsBAfAVyda69Pe1yGbBW4ywVwbB2fBRSc+0y8/5AqSpL0KpqqLo2BHRKHxMnnuFvW/xxUkD65VF76DBpb5OG0vy8rfFVtBrzQbA/f9AzFZ0KT+t0iKiKCNRt7kuMriNAlTq6pvkti33Eq9whh8N0YhUqlPcP9ybRjs1pvrfEv5j8NkyzgFatS5PNjKo+NurinjxtqIhcgedh3cN8SIZ9by6GhBI8YEkuBVHpNXlyAkQyHP2SloG7CJcQW9tOzu3VwFlVyFl8Bn8AZ8AMctnk1RxFHwDtyxCBG7DNbrMGlLoIWVXfaVR8f3ExQsDxf7wpeZwp067eMxaUsOg7fFBiUZsiPgjOX6pCL3zgDbAvZIp8HjIHF2K/VturDVqElhrJ8tShdbFqcUQW4rIK3FfrCpTGHS47wGHZbFEsjM9iPP8M3j/pYPOI+smgV8kZZyxRRr8sfZlh4LOI/0UReiiLPfV4e4/pwlB3571J3GsIKCfHWcp7cyLIzyNfGCHqkzxjaxzR0tV1CiUChYLzzszPndKx3mM0vyH+SqdRrW1UfnIT2Zh7hhtilZ4/wSV1AcOeRntmJXE2dS+9mg5VzV/xRkq1NjYSb8I8AAdTOa+zQjMmsAAAAASUVORK5CYII=")}.bk-tool-icon-pan{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCRTI5MDhEODIwQjUxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCRTI5MDhEOTIwQjUxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkJFMjkwOEQ2MjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkJFMjkwOEQ3MjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+OXzPwwAAAKNJREFUeNrsVsEKgCAM3cyj0f8fuwT9XdEHrLyVIOKYY4kPPDim0+fenF+3HZi4nhFec+Rs4oCPAALwjDVUsKMWA6DNAFX6YXcMYIERdRWIYBzAZbKYGsSKex6mVUAK8Za0TphgoFTbpSvlx3/I0EQOILO2i/ibegLk/mgVONM4JvuBVizgkGH3XTGrR/xlV0ycbO8qCeMN54wdtVQwSTFwCzAATqEZUn8W8W4AAAAASUVORK5CYII=")}.bk-tool-icon-polygon-select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAgCAYAAAB6kdqOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFMzNBREIxOTQ0MUExMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFMzNBREIxQTQ0MUExMUU0QTE0ODk2NTE1M0M0MkZENCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkUzM0FEQjE3NDQxQTExRTRBMTQ4OTY1MTUzQzQyRkQ0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkUzM0FEQjE4NDQxQTExRTRBMTQ4OTY1MTUzQzQyRkQ0Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+xB9jgwAAAe5JREFUeNrsmL1LAzEYxu9KUVDBW8RBhRscXNSCoyA6uIl0kYqIXFcXBRdBoYpuDi7iYEFbkFZPpX6sin+BtAhODloHRZTaSkEUUZ/A23rUer275mjFBn40hJA8eZI3ea+iGjn4FL5LCkigHiQ5trM5HEPuQaFQcQhlVpy0GoFWpF2hmKe/lfaUWUHZYsRSM2Vn/9CSQ5LNu2Bq/LI7Qw6KgqSNc5gavywdqgiqRFklyv7doS7q7flrUbYImkG61FvmAU9gBvhLHWUrYIucfwdxM6kNL4fqwBzV18AHOAaNYJo1BsOqDFyiKAp68BA0Cx6BD4yDc8ql+0FC008Gp4HQtttOh6JgAVSDF/BM7WmdZyQCUct6giSTkdYCpqjup+0JghqwaXCMSYhibknFOFQFwnRIl0AbWKXtUSy42wuuIMplNcoewDB9XdyB2gLbYzQTiEKUYtShHjBK9RM6JxOgCZxxvCo2IIohOX/pwMJ1D3STCBWMgTeCZyYQI+I/3jKNmFuNe5d0zyRsSt68yojnOl+UeUEXuAc3dLew67WTs5gYzZUpvtxD3UEurINdam8HDeCIsyNMTB8cCeA344qCsyNrBbFOrfQPxQWHyCkkJhPR8/lcYoJe6XJj98GAXXkIE6IRI+S4lHXoS4ABAP0ljy6tE4wBAAAAAElFTkSuQmCC")}.bk-tool-icon-redo{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wwGEDEBYlsi0wAAAYBJREFUWMPtl71Lw0AYxn9ppVAodKoUBGfHDtJJR0FRFAc5uMEbBFcdBcXi4G5Hhw5ZAkFQHASho07i0L+hUCi4KBSKQsHlLYSS0iQ0rcI9EMjHfTz3e58LCVhZWf1vOVEbup6fBTbkWAOyQEUet4AB8Ao0gabRajATg67nl4ErQAHFiON+AT5QM1p1UzHoen4eOAdOgELC8XtAHbg2WvWnZlCoPQLVKUXpDdhLQtMJMVcRc8sh7TvAA/AEfEj2kCyWgG1gH1ga03fHaNVKbFDIvYdM0AVqQGNS+GUzHUluyyEmV+OQdAID54CXkLI+AwdGq16clbueXwDugM2Qcq8brX6ijLMQOL8MMVc3Wp0mCZ0saMv1/BvZaENVZa6Lqb4Hk0pKfg/sjuzuFaNVZ1L/TNoGJbOHkr+hCsDZnyAYIHkM3AZu9YHFSdnOMDs1gHbgOj9S9tkTdD2/CHzGjIQzL4Lpfs2kTXKUnCU4hmQO+I5Cbl4ES/YfwcrKyiqefgEvB2gLTkQWKgAAAABJRU5ErkJggg==")}.bk-tool-icon-reset{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCRTI5MDhFMDIwQjUxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyOUMzNDE3NDIwQkIxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkJFMjkwOERFMjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkJFMjkwOERGMjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+kFHGtQAAAm1JREFUeNrMmE9ExFEQx3+7ZYmlLrEsUUTHaEV0iESJVqduXaJr1xKlFB1bdYqoQ9GlFBFdikgpIhLd0rLqUsQqrW2G7+YZr+2993vaHT6H3583M795897M+0U2t3cCR6kh+kA3rtvx7IYoEGfEMSi4GIk4OJgg5ogRot5wzBvBhmaJnI2xqMW7dcQC8UCMWzgX4N1xjF2ALq8OctROiGkiHrhLHDpOoNOLg5xXF0Sn5lmWWCUGiBRRC1K4t4p3pLCuKyVnnXMwAUVJcT+HfFo3SH5ePGPI24TmA1Pl8rJcBGPEvsa5I6KVWDNcmQW824qxqiRhI+bi4IxmWjOYuneH/HvH2Ixmumd8bjNhhad8lxgSzrfp8jUa/L/wlI8KZ3h1T4bdB30Kb9zz4t6YbgurlIMBdoBHUQiGTBx8JYoKPqVe0ftFNInnW8J20SSCjRWM8k8E1S+TNfbZYyQ59yJEg0kjw1QyB42k1iI6ReXLfEWSK8iHJnJVsYqN8jtammuFc/FOr3juU7Ia+39uM7fiuq8aVrEqp+J6BPWzahw8IPLKdTPKUNU4yJ3Fhqb1inu0y7qeRNVYsWkWFkXPl0QZ8iVbohFmW0s2DmY1jSUX8mUPzi1rmoLML2eXsvsgR/FO3JtAix53nNZ96FDlDrasW35eKGniRRPJeywck9VdOjTdayL3Ahv5MC1/xy+Hp1Iq7BGHMHatjOEqMUgMlxmbVsaEOpMk4GSnp0VyCedyLtuMTlhRD1ZaPoRjeejoMf1HE7VUPkW04Jz7Ztm9rGHslM1Hhjl2xlCn+4muQP/77RyHdf799uli5FuAAQC+l5Sj5nEBdwAAAABJRU5ErkJggg==")}.bk-tool-icon-resize{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAgCAYAAAB3j6rJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBODVDNDBCQjIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBODVDNDBCQzIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjMyMUREOEQ4MjBCMjExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkE4NUM0MEJBMjBCMzExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+nIbQ0AAAAIJJREFUeNpiXLhs5X8G7ICRgTYAq31MDIMEwBzyERoCyJhWAN2ej4MqRFiIjUMahczgSyMsNE4PxACBQZlrcAFsuYkcLECpQwZNiIw6ZNQhow4ZdcioQ0YdMuoQerRZkQE/vdqwgypqQD7+MIBuANn9f1CnEcbRXIMjd4zM0QCAAAMAbdAPQaze1JcAAAAASUVORK5CYII=")}.bk-tool-icon-save{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMjFERDhENjIwQjIxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozMjFERDhENzIwQjIxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjMyMUREOEQ0MjBCMjExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjMyMUREOEQ1MjBCMjExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+h5hT8AAAAKBJREFUeNpiWbhs5QcGBgZ+hgECTAwDDGAO+AjEjGj4Lw5xUrAAkl3ocr8IhQAzjT3PRu0o+I+EHw65NDDqgJHrABYC8t9JMIuRmiHACS2IKC0LOKH0X1JDAOTzs0BsBs3XlIKz5KSBRCA+RQXLjwNxNDlp4BoQm9Mo7fGPZsNRB4w6YNQBI94BfwfaAV9G08CoA9DbA/xUavkMvRAACDAAaPgYViexODkAAAAASUVORK5CYII=")}.bk-tool-icon-tap-select{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3NzIwRUFGMDYyMjE2ODExOTdBNUNBNjVEQTY5OTRDRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCOTJBQzE0RDQ0RDUxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCOTJBQzE0QzQ0RDUxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTQ0QzIwMUM1RjIxNjgxMUE3QkFFMzhGRjc2NTI3MjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzcyMEVBRjA2MjIxNjgxMTk3QTVDQTY1REE2OTk0Q0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6eYZ88AAADLklEQVR42rSXf2TUYRzHv7tuGcfE6Vwb5zLSSjEj7Y9KWqfEmFZJP+yPMdKKmUrrn0iUfjhWlLFi6YfNrF+StBoTo39iYkTGco4xxxG59P7k/T2PT8/37nu3bx9ezvPj+zyf5/PreS78bGLS8SmrwE6yje3NHJsDBTALpknBz6JhH3NiYAB0gHqPOVv52wJ6QQ48BzdAttTioRJjdeA8mAHHS2xuk3p+M8M16ipVQE49Ds6CiFO9RLjGONf05QLx6wPQaBlbBlPgJVgkP0ETiIJ2sB/E1XfimjfgBOOlKDUqCGOcqBcQnw6BYW5YTo4wbvQhMmCfGRemC2rBiGXzWUb+kM/NRZ6CHWBM9ce5R61NgX6ayhSJ5EPlItlDRNkz4JbFHf06BkSzHjXxM+gDv1S/mPUo2AXWgt9UUHL/IVhS8yUV1/EbV3o4N+NaoE9Fu/i827K5pNYHnqAVJECShWmAaddpscYFFXwR7vnXBRGlnUN/L6kqKJlxnRUuDbaDBiL+vst5d4gpcpBrqk/2jIgCKVUolhntplzivHmwh4stGOPfwBWwl/2dpp8p7xjQZqFLiQJtauKkivYm+kzccpK57yXfOUe+P23JqAnVbhMFmlXntCWnxbT31am9ZJ4BJifsUmNTqt0cYhA5ypympPg7VkEKunPbVb8cIG+0kyHLJZNR7fUMooUKFHAPkfQo58VLK+RzwRDd4FdWG9mjpaAXzqkJa1R7kQttqEABWXMjOOxxVRfnhRm5URX1prk/0pQHwNcKlchZ+jdpC+hFdVqO0my9Hj5dkYgCn1Rfh/KdlNDHrJhPqlDih+IfBd6qwpOgEqYMsorJ2HtWxtagLJDn/W3KRfPOZhoeBJfZPgVeGKeKrkQBh5dLXl25Ny3pc4/1fkTdbvFqFQgbxWeYD0hXulhQ0pYiM1jG547fcbMQpVnHTZEn9W3ljsCzwHxCdVteNHIZvQa7/7cC7nV6zHIfyFP9EXjFa7YxKAVqPP4bxhhoLWW+z9JyCb6M/MREg59/RlmmXbmneIybB+YC/ay+yrffqEddDzwGvKxxDmzhc0tc80XVgblqFfgjwAAPubcGjAOl1wAAAABJRU5ErkJggg==")}.bk-tool-icon-undo{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wwGEAgO/GCy+AAAAXlJREFUWMPtlr1LQzEUxX+1ohQKuhQK/Sc6SCcdBUVQFCSQwQwOjjoKisXB3a5Ch7c8CA6iKAgddRKHjs6FQtGpUBCEoksK5RE179FPyIEs+bg59+TcJODh4THdSA0qUBDqNLBq2jKQBopmuA50gWegBtSUFN2REAxCnQfOAQEsOC5rAxooKylaQyEYhDoDnACHQDZhmA5QAS6UFJ8DI2hUuwVKA3LIC7BlUzOVgFwRuAcKluEmcAM8AB/Gexgv5oANYPuXtQ1Dsp6YoFHu1bJBCygD1f/Mb4pp3/g2b0lwqV/JVAxyc8CT5VgfgV0lRSdmslngGlizHPeKkuILYDZGzDMLuYqS4iiJ6UxC60GoL02h9VAye506KxiEugC8Rar1Dthxvc+SYsZx3nGEXBPYGzY5JwWNV96BTF/3gZLiahRPnYuCmxFyDaA6trc4CPV3zBiLSor2uD04eb8ZByWHqtz0K/iHkvO9W35SqjiKnP/ne3h4eIwOP9GxagtPmsh6AAAAAElFTkSuQmCC")}.bk-tool-icon-wheel-zoom{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAgCAYAAABpRpp6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCRTI5MDhEQzIwQjUxMUU0ODREQUYzNzM5QTM2MjBCRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCRTI5MDhERDIwQjUxMUU0ODREQUYzNzM5QTM2MjBCRSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkJFMjkwOERBMjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkJFMjkwOERCMjBCNTExRTQ4NERBRjM3MzlBMzYyMEJFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+sFLapAAAA8xJREFUeNq8WH9k1VEU/+67ecTYxKM8xlJiifKIMUqUKMvy1CqbEmUxJZbSlGXTLBuJpYi18dpqStOzacT+WcTXpkiRUjziETEeY9bnzHm5O53vj/te7fDx3r3fc+/9fM/3nHPPvWWP0mOOIlVAC3AQqOc2SRZ4A9Cg58CSNrj1+FEnSIYfPynHTyOQArYCO/jRPPAJGAcmMM9f87vKfG3AF+AucMAgS5LgRZ4CH/mFrARkieAs8Aw4ASSBckaS++jZLOv6El4HjAKDwPoIa28GXgLdFmQv4WcO2BVBnXTmeIxK+D5wzLGXa8D1CGT78NPPhjFlGnjAmBbPSLefx65IBf+eZZ81hfznIfsr+W0eaACa2G3MhbuAt8CUD1kyRIfongDa4affhW4Nu2Oj0d2Bfg+6Y2UIukr2x4ShkAMOMQlNyLcmgVqj7z2wk17UDDosFOOYMOdPQ+dkyBcZFkb8DGxz2ckTwrKHA8g6HMn7gQWjbzsHqZSUmJ8sej6Cq7WzrhkzKVeYnmSEXSBM6I17RZ+WNWRfJ6z7K2xy1umUc7lGDizIkDL+AsNRXs6U3YpOUrRfWwS01K2noIuLzg+iTcFSiFLKlQPi8+aNAIwri24QlstaEM6JdoIsHBOdiyJl9RntfiXazUljEdJb3IKw1F10Q/Krtin0KaSD5Ido77MYK10sG0S4ByjzwW2LRT3pYlxLRBFpGM91/r9kRJuC/FbEnVEmhEwQYRqw7IMuC8LjnAKllSeBhEI0Qc8U636luWinWxYPqoFCnuxmX16VR9ldCvINqOH/NK5alpe8NY8qL5Nnl/GMFJhU6g2SZtqaw1xCkrss2pGEFhLp0CxuGow83+BDdoDn+FP8hJFeYusNlODL9LI/ubKLRRxDKfamuaNWRBx4o9TI49NDD9yjSdn9NKFa5jTGrdrIKpw1FJCtU8h6Rp/HwbVyBNOOSGtKGHJKtGdAao/NBO4aWrecS9mwQiuU8KLoi1nOEfepQ6TsFXVxnnO0NWFZEdVZjK8RaSgXoHtGbihwh4ViCM+LvhaL8VJ3xscdqnwOCk4xhDNKYNRHPOZfCakbzGOS+SWyloX8KsIj4lNScLwIuTsgsq+ASnFkmor4JdJayopKeEHZGOJ8OzMoatIkF0XvxIm5cGhcUtyhVqlrh4rNNoU8fI+jOCUs3cYIk14L63py9yo2D7fyBZ+t3AGuWgTmiFOCuCIvHuHFo6QbCpxm4GLIxZ+880j/K8Lm593EVZqnXF9N8UXIFt7zgwoeunDZCJzju44M+nKlEP4twAAD1RclkNDukAAAAABJRU5ErkJggg==")}
2 /*# sourceMappingURL=bokeh.min.css.map */
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,4 +1,4
1 FROM python:3.7-slim
1 FROM python:2.7-slim
2
2
3 # set working directory
3 # set working directory
4 RUN mkdir /radarsys
4 RUN mkdir /radarsys
@@ -139,7 +139,7 class DownloadFileForm(forms.Form):
139 if device_type == 'dds_rest':
139 if device_type == 'dds_rest':
140 self.fields['format'].choices = DDS_FILE_FORMAT
140 self.fields['format'].choices = DDS_FILE_FORMAT
141
141
142 if device_type == 'rc':
142 if device_type == 'pedestal':
143 self.fields['format'].choices = RC_FILE_FORMAT
143 self.fields['format'].choices = RC_FILE_FORMAT
144
144
145 if device_type == 'jars':
145 if device_type == 'jars':
@@ -20,17 +20,17 from django.db.models.signals import post_save
20 from django.dispatch import receiver
20 from django.dispatch import receiver
21
21
22 from apps.main.utils import Params
22 from apps.main.utils import Params
23 from apps.rc.utils import RCFile
23 from apps.pedestal.utils import RCFile
24 from apps.jars.utils import RacpFile
24 from apps.jars.utils import RacpFile
25 from devices.dds import api as dds_api
25 from devices.dds import api as dds_api
26 from devices.dds import data as dds_data
26 from devices.dds import data as dds_data
27
27
28
28
29 DEV_PORTS = {
29 DEV_PORTS = {
30 'rc' : 2000,
30 'pedestal': 80,
31 'dds' : 2000,
31 'dds' : 2000,
32 'jars' : 2000,
32 'jars' : 2000,
33 'usrp' : 2000,
33 'usrp_rx' : 2000,
34 'cgs' : 8080,
34 'cgs' : 8080,
35 'abs' : 8080,
35 'abs' : 8080,
36 'dds_rest': 80
36 'dds_rest': 80
@@ -65,11 +65,11 DEV_STATES = (
65 )
65 )
66
66
67 DEV_TYPES = (
67 DEV_TYPES = (
68 ('', 'Select a device type'),
68 ('', 'Select a device type'),
69 ('rc', 'Radar Controller'),
69 ('pedestal', 'Pedestal Controller'),
70 ('dds', 'Direct Digital Synthesizer'),
70 ('generator', 'Pulse Generator'),
71 ('jars', 'Jicamarca Radar Acquisition System'),
71 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
72 ('usrp', 'Universal Software Radio Peripheral'),
72 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
73 ('cgs', 'Clock Generator System'),
73 ('cgs', 'Clock Generator System'),
74 ('abs', 'Automatic Beam Switching'),
74 ('abs', 'Automatic Beam Switching'),
75 ('dds_rest', 'Direct Digital Synthesizer_REST'),
75 ('dds_rest', 'Direct Digital Synthesizer_REST'),
@@ -205,7 +205,7 class Device(models.Model):
205 self.message = '40|{}'.format(str(e))
205 self.message = '40|{}'.format(str(e))
206 return False
206 return False
207
207
208 elif self.device_type.name=='rc':
208 elif self.device_type.name=='pedestal':
209 headers = {'content-type': "application/json",
209 headers = {'content-type': "application/json",
210 'cache-control': "no-cache"}
210 'cache-control': "no-cache"}
211
211
@@ -287,7 +287,7 class Campaign(models.Model):
287
287
288 for conf in configurations:
288 for conf in configurations:
289 params.add(conf.jsonify(), 'configurations')
289 params.add(conf.jsonify(), 'configurations')
290 if conf.device.device_type.name=='rc':
290 if conf.device.device_type.name=='pedestal':
291 for line in conf.get_lines():
291 for line in conf.get_lines():
292 params.add(line.jsonify(), 'lines')
292 params.add(line.jsonify(), 'lines')
293
293
@@ -427,10 +427,10 class Experiment(models.Model):
427
427
428 confs = []
428 confs = []
429 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
429 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
430 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
430 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='pedestal' and conf.mix]
431 if rc_mix:
431 if rc_mix:
432 for conf in allconfs:
432 for conf in allconfs:
433 if conf.device.device_type.name == 'rc' and not conf.mix:
433 if conf.device.device_type.name == 'pedestal' and not conf.mix:
434 continue
434 continue
435 confs.append(conf)
435 confs.append(conf)
436 else:
436 else:
@@ -508,7 +508,7 class Experiment(models.Model):
508
508
509 for conf in configurations:
509 for conf in configurations:
510 params.add(conf.jsonify(), 'configurations')
510 params.add(conf.jsonify(), 'configurations')
511 if conf.device.device_type.name=='rc':
511 if conf.device.device_type.name=='pedestal':
512 for line in conf.get_lines():
512 for line in conf.get_lines():
513 params.add(line.jsonify(), 'lines')
513 params.add(line.jsonify(), 'lines')
514
514
@@ -624,7 +624,7 class Configuration(PolymorphicModel):
624
624
625 data['device_type'] = self.device.device_type.name
625 data['device_type'] = self.device.device_type.name
626
626
627 if self.device.device_type.name == 'rc':
627 if self.device.device_type.name == 'pedestal':
628 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
628 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
629 data['delays'] = self.get_delays()
629 data['delays'] = self.get_delays()
630 data['pulses'] = self.get_pulses()
630 data['pulses'] = self.get_pulses()
@@ -664,7 +664,7 class Configuration(PolymorphicModel):
664 params = Params({})
664 params = Params({})
665 params.add(self.jsonify(), 'configurations')
665 params.add(self.jsonify(), 'configurations')
666
666
667 if self.device.device_type.name=='rc':
667 if self.device.device_type.name=='pedestal':
668 for line in self.get_lines():
668 for line in self.get_lines():
669 params.add(line.jsonify(), 'lines')
669 params.add(line.jsonify(), 'lines')
670
670
@@ -689,7 +689,7 class Configuration(PolymorphicModel):
689 else:
689 else:
690 data = params.get_conf(dtype=self.device.device_type.name)
690 data = params.get_conf(dtype=self.device.device_type.name)
691
691
692 if data['device_type']=='rc':
692 if data['device_type']=='pedestal':
693 self.clean_lines()
693 self.clean_lines()
694 lines = data.pop('lines', None)
694 lines = data.pop('lines', None)
695 for line_id in lines:
695 for line_id in lines:
@@ -1,6 +1,6
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load bootstrap4 %}
2 {% load bootstrap4 %}
3 {% block content-title %}Integrated Radar System{% endblock %}
3 {% block content-title %}Integrated Weather Radar System{% endblock %}
4 {% block content-suptitle %}at JRO{% endblock %}
4 {% block content-suptitle %}at JRO{% endblock %}
5
5
6 {% block content %}
6 {% block content %}
@@ -23,21 +23,21 except ImportError:
23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25
25
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
26 from apps.pedestal.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
31 from apps.usrp_rx.forms import USRPConfigurationForm
32 from apps.dds_rest.forms import DDSRestConfigurationForm
32 from apps.dds_rest.forms import DDSRestConfigurationForm
33 from .utils import Params
33 from .utils import Params
34
34
35 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
35 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
36 from apps.cgs.models import CGSConfiguration
36 from apps.cgs.models import CGSConfiguration
37 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
37 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
38 from apps.usrp.models import USRPConfiguration
38 from apps.usrp_rx.models import USRPConfiguration
39 from apps.abs.models import ABSConfiguration
39 from apps.abs.models import ABSConfiguration
40 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
40 from apps.pedestal.models import RCConfiguration, RCLine, RCLineType, RCClock
41 from apps.dds.models import DDSConfiguration
41 from apps.dds.models import DDSConfiguration
42 from apps.dds_rest.models import DDSRestConfiguration
42 from apps.dds_rest.models import DDSRestConfiguration
43
43
@@ -46,23 +46,23 from radarsys.celery import app
46
46
47 #comentario test
47 #comentario test
48 CONF_FORMS = {
48 CONF_FORMS = {
49 'rc': RCConfigurationForm,
49 'pedestal': RCConfigurationForm,
50 'dds': DDSConfigurationForm,
50 'dds': DDSConfigurationForm,
51 'dds_rest': DDSRestConfigurationForm,
51 'dds_rest': DDSRestConfigurationForm,
52 'jars': JARSConfigurationForm,
52 'jars': JARSConfigurationForm,
53 'cgs': CGSConfigurationForm,
53 'cgs': CGSConfigurationForm,
54 'abs': ABSConfigurationForm,
54 'abs': ABSConfigurationForm,
55 'usrp': USRPConfigurationForm,
55 'usrp_rx': USRPConfigurationForm,
56 }
56 }
57
57
58 CONF_MODELS = {
58 CONF_MODELS = {
59 'rc': RCConfiguration,
59 'pedestal': RCConfiguration,
60 'dds': DDSConfiguration,
60 'dds': DDSConfiguration,
61 'dds_rest': DDSRestConfiguration,
61 'dds_rest': DDSRestConfiguration,
62 'jars': JARSConfiguration,
62 'jars': JARSConfiguration,
63 'cgs': CGSConfiguration,
63 'cgs': CGSConfiguration,
64 'abs': ABSConfiguration,
64 'abs': ABSConfiguration,
65 'usrp': USRPConfiguration,
65 'usrp_rx': USRPConfiguration,
66 }
66 }
67
67
68 MIX_MODES = {
68 MIX_MODES = {
@@ -260,7 +260,7 def device_new(request):
260 kwargs = {}
260 kwargs = {}
261 kwargs['form'] = form
261 kwargs['form'] = form
262 kwargs['title'] = 'Device'
262 kwargs['title'] = 'Device'
263 kwargs['suptitle'] = 'New_2'
263 kwargs['suptitle'] = 'New'
264 kwargs['button'] = 'Create'
264 kwargs['button'] = 'Create'
265 kwargs['menu_devices'] = 'active'
265 kwargs['menu_devices'] = 'active'
266
266
@@ -958,7 +958,7 def experiment_summary(request, id_exp):
958 code_id = 0
958 code_id = 0
959 tx_line = {}
959 tx_line = {}
960
960
961 for configuration in configurations.filter(device__device_type__name = 'rc'):
961 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
962
962
963 if configuration.mix:
963 if configuration.mix:
964 continue
964 continue
@@ -1129,7 +1129,7 def experiment_verify(request, id_exp):
1129 kwargs['jars'] = configuration
1129 kwargs['jars'] = configuration
1130
1130
1131 #--------------------- RC ----------------------:
1131 #--------------------- RC ----------------------:
1132 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1132 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
1133 rc_conf = True
1133 rc_conf = True
1134 rc = configuration
1134 rc = configuration
1135
1135
@@ -1360,7 +1360,7 def dev_conf_new(request, id_exp=0, id_dev=0):
1360 conf.author = request.user
1360 conf.author = request.user
1361 conf.save()
1361 conf.save()
1362
1362
1363 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1363 if 'template' in request.GET and conf.device.device_type.name == 'pedestal':
1364 lines = RCLine.objects.filter(
1364 lines = RCLine.objects.filter(
1365 rc_configuration=request.GET['template'])
1365 rc_configuration=request.GET['template'])
1366 for line in lines:
1366 for line in lines:
@@ -1375,7 +1375,7 def dev_conf_new(request, id_exp=0, id_dev=0):
1375 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1375 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1376 line.params = json.dumps(line_params)
1376 line.params = json.dumps(line_params)
1377 line.save()
1377 line.save()
1378 elif conf.device.device_type.name == 'rc':
1378 elif conf.device.device_type.name == 'pedestal':
1379 clk = RCClock(rc_configuration=conf)
1379 clk = RCClock(rc_configuration=conf)
1380 clk.save()
1380 clk.save()
1381
1381
@@ -1390,7 +1390,6 def dev_conf_new(request, id_exp=0, id_dev=0):
1390 if id_dev != 0:
1390 if id_dev != 0:
1391 device = Device.objects.get(pk=id_dev)
1391 device = Device.objects.get(pk=id_dev)
1392 kwargs['device'] = device.device_type.name
1392 kwargs['device'] = device.device_type.name
1393 print(id_exp)
1394 return render(request, 'dev_conf_edit.html', kwargs)
1393 return render(request, 'dev_conf_edit.html', kwargs)
1395
1394
1396
1395
1 NO CONTENT: file renamed from apps/rc/__init__.py to apps/pedestal/__init__.py
NO CONTENT: file renamed from apps/rc/__init__.py to apps/pedestal/__init__.py
1 NO CONTENT: file renamed from apps/rc/admin.py to apps/pedestal/admin.py
NO CONTENT: file renamed from apps/rc/admin.py to apps/pedestal/admin.py
1 NO CONTENT: file renamed from apps/rc/fixtures/rc_initial_data.json to apps/pedestal/fixtures/rc_initial_data.json
NO CONTENT: file renamed from apps/rc/fixtures/rc_initial_data.json to apps/pedestal/fixtures/rc_initial_data.json
@@ -21,7 +21,6 def create_choices_from_model(model, conf_id, all_choice=False):
21
21
22 return choices
22 return choices
23
23
24
25 class ExtFileField(forms.FileField):
24 class ExtFileField(forms.FileField):
26 """
25 """
27 Same as forms.FileField, but you can specify a file extension whitelist.
26 Same as forms.FileField, but you can specify a file extension whitelist.
@@ -62,16 +61,11 class RCConfigurationForm(forms.ModelForm):
62
61
63 if instance and instance.pk:
62 if instance and instance.pk:
64
63
65 devices = Device.objects.filter(device_type__name='rc')
64 devices = Device.objects.filter(device_type__name='pedestal')
66 if instance.experiment:
65 if instance.experiment:
67 self.fields['experiment'].widget.attrs['read_only'] = True
66 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
67 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
68 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
69
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
70 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['readonly'] = True
71 self.fields['experiment'].widget.attrs['readonly'] = True
@@ -97,7 +91,6 class RCConfigurationForm(forms.ModelForm):
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
91 clk = RCClock.objects.filter(rc_configuration=conf).first()
98 if clk:
92 if clk:
99 conf.clock_in = clk.frequency
93 conf.clock_in = clk.frequency
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
101 conf.save()
94 conf.save()
102 return conf
95 return conf
103
96
@@ -4,7 +4,7 import ast
4 import json
4 import json
5 import requests
5 import requests
6 import numpy as np
6 import numpy as np
7 from base64 import b64encode
7 import base64
8 from struct import pack
8 from struct import pack
9
9
10 from django.db import models
10 from django.db import models
@@ -14,8 +14,12 from django.core.validators import MinValueValidator, MaxValueValidator
14 from apps.main.models import Configuration
14 from apps.main.models import Configuration
15 from apps.main.utils import Params
15 from apps.main.utils import Params
16 from devices.rc import api
16 from devices.rc import api
17 from apps.rc.utils import RCFile
17 from apps.pedestal.utils import RCFile
18
18
19 AXIS_VALUE = (
20 ('AZI', 'azimuth'),
21 ('ELE', 'elevation')
22 )
19
23
20 LINE_TYPES = (
24 LINE_TYPES = (
21 ('none', 'Not used'),
25 ('none', 'Not used'),
@@ -72,41 +76,43 ror = lambda val, r_bits: \
72
76
73 class RCConfiguration(Configuration):
77 class RCConfiguration(Configuration):
74
78
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
79 axis = models.CharField(
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
80 verbose_name='Axis',
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
81 max_length=3,
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
82 choices=AXIS_VALUE,
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
83 null=False,
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
84 blank=False
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
85 )
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
86
83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
87 speed = models.FloatField(
84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
88 verbose_name='Speed',
85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
89 validators=[MinValueValidator(-20), MaxValueValidator(20)],
86 total_units = models.PositiveIntegerField(default=0)
90 blank=False,
87 mix = models.BooleanField(default=False)
91 null=False
92 )
93
94 table = models.CharField(
95 verbose_name="Table",
96 max_length=100,
97 default='',
98 blank=False,
99 null=False
100 )
88
101
89 class Meta:
102 class Meta:
90 db_table = 'rc_configurations'
103 db_table = 'pedestal_configurations'
104
105 def __str__(self):
106 return self.label
91
107
92 def get_absolute_url_plot(self):
108 def get_absolute_url_plot(self):
93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
109 return reverse('url_plot_pedestal_pulses', args=[str(self.id)])
94
110
95 @property
111 @property
96 def ipp_unit(self):
112 def ipp_unit(self):
97
113
98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
114 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99
115
100 @property
101 def us2unit(self):
102
103 return self.clock_in/self.clock_divider
104
105 @property
106 def km2unit(self):
107
108 return 20./3*(self.clock_in/self.clock_divider)
109
110 def clone(self, **kwargs):
116 def clone(self, **kwargs):
111
117
112 lines = self.get_lines()
118 lines = self.get_lines()
@@ -156,7 +162,7 class RCConfiguration(Configuration):
156 if id:
162 if id:
157 data = Params(params).get_conf(id_conf=id)
163 data = Params(params).get_conf(id_conf=id)
158 else:
164 else:
159 data = Params(params).get_conf(dtype='rc')
165 data = Params(params).get_conf(dtype='pedestal')
160
166
161 #print(data)
167 #print(data)
162 # self.name = data['name']
168 # self.name = data['name']
@@ -531,9 +537,28 class RCConfiguration(Configuration):
531 return True
537 return True
532
538
533 def start_device(self):
539 def start_device(self):
534
540 print("Entró al start")
535 try:
541 try:
536 payload = self.request('start', 'post')
542 pedestal = RCConfiguration.objects.get(pk=self)
543 pedestal_axis = pedestal.get_axis_display()
544 print(pedestal)
545 print(pedestal_axis)
546 table = pedestal.table
547 print(table)
548 table_bytes = table.encode('ascii')
549 table_base64 = base64.b64encode(table_bytes)
550 table_base64 = table_base64.decode('ascii')
551 print(table_base64)
552 data = {'axis': pedestal_axis, 'speed': pedestal.speed, 'table': table_base64}
553 print(data)
554 data = json.dumps(data)
555 print(data)
556 data_bytes = data.encode('ascii')
557 data_base64 = base64.b64encode(data_bytes)
558 data_base64 = data_base64.decode('ascii')
559 print(data_base64)
560 payload = self.request('table?/params=' + data_base64, 'get')
561 print(payload)
537 self.message = 'RC start: {}'.format(payload['start'])
562 self.message = 'RC start: {}'.format(payload['start'])
538 if payload['start']=='ok':
563 if payload['start']=='ok':
539 self.device.status = 3
564 self.device.status = 3
@@ -555,11 +580,13 class RCConfiguration(Configuration):
555
580
556 if not raw:
581 if not raw:
557 clock = RCClock.objects.get(rc_configuration=self)
582 clock = RCClock.objects.get(rc_configuration=self)
583 print(clock)
558 if clock.mode:
584 if clock.mode:
559 data = {'default': clock.frequency}
585 data = {'default': clock.frequency}
560 else:
586 else:
561 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
587 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
562 payload = self.request('setfreq', 'post', data=json.dumps(data))
588 payload = self.request('setfreq', 'post', data=json.dumps(data))
589 print(payload)
563 if payload['command'] != 'ok':
590 if payload['command'] != 'ok':
564 self.message = 'RC write: {}'.format(payload['command'])
591 self.message = 'RC write: {}'.format(payload['command'])
565 else:
592 else:
@@ -636,7 +663,7 class RCConfiguration(Configuration):
636
663
637
664
638 def get_absolute_url_import(self):
665 def get_absolute_url_import(self):
639 return reverse('url_import_rc_conf', args=[str(self.id)])
666 return reverse('url_import_pedestal_conf', args=[str(self.id)])
640
667
641
668
642 class RCLineCode(models.Model):
669 class RCLineCode(models.Model):
1 NO CONTENT: file renamed from apps/rc/static/css/bokeh-0.11.1.min.css to apps/pedestal/static/css/bokeh-0.11.1.min.css
NO CONTENT: file renamed from apps/rc/static/css/bokeh-0.11.1.min.css to apps/pedestal/static/css/bokeh-0.11.1.min.css
1 NO CONTENT: file renamed from apps/rc/static/js/bokeh-0.11.1.min.js to apps/pedestal/static/js/bokeh-0.11.1.min.js
NO CONTENT: file renamed from apps/rc/static/js/bokeh-0.11.1.min.js to apps/pedestal/static/js/bokeh-0.11.1.min.js
1 NO CONTENT: file renamed from apps/rc/static/js/bokeh-0.12.1.min.js to apps/pedestal/static/js/bokeh-0.12.1.min.js
NO CONTENT: file renamed from apps/rc/static/js/bokeh-0.12.1.min.js to apps/pedestal/static/js/bokeh-0.12.1.min.js
1 NO CONTENT: file renamed from apps/rc/static/js/bokeh-2.2.1.min.js to apps/pedestal/static/js/bokeh-2.2.1.min.js
NO CONTENT: file renamed from apps/rc/static/js/bokeh-2.2.1.min.js to apps/pedestal/static/js/bokeh-2.2.1.min.js
1 NO CONTENT: file renamed from apps/rc/static/js/cr.js to apps/pedestal/static/js/cr.js
NO CONTENT: file renamed from apps/rc/static/js/cr.js to apps/pedestal/static/js/cr.js
1 NO CONTENT: file renamed from apps/rc/static/js/jquery-ui.min.js to apps/pedestal/static/js/jquery-ui.min.js
NO CONTENT: file renamed from apps/rc/static/js/jquery-ui.min.js to apps/pedestal/static/js/jquery-ui.min.js
@@ -5,12 +5,12
5 <script type="text/javascript">
5 <script type="text/javascript">
6
6
7 $("#id_line_type").change(function() {
7 $("#id_line_type").change(function() {
8 var url = "{% url 'url_add_rc_line' dev_conf.id %}";
8 var url = "{% url 'url_add_pedestal_line' dev_conf.id %}";
9 document.location = url + $(this).val()+"/";
9 document.location = url + $(this).val()+"/";
10 });
10 });
11
11
12 $("#id_code").change(function() {
12 $("#id_code").change(function() {
13 var url = "{% url 'url_add_rc_line' dev_conf.id line_type.id %}";
13 var url = "{% url 'url_add_pedestal_line' dev_conf.id line_type.id %}";
14 document.location = url+ "code/" + $(this).val() + "/";
14 document.location = url+ "code/" + $(this).val() + "/";
15 });
15 });
16
16
1 NO CONTENT: file renamed from apps/rc/templates/rc_conf.html to apps/pedestal/templates/rc_conf.html
NO CONTENT: file renamed from apps/rc/templates/rc_conf.html to apps/pedestal/templates/rc_conf.html
@@ -42,7 +42,7
42 <script type="text/javascript">
42 <script type="text/javascript">
43
43
44 $("#div_lines").on("click", "button[name=bt_remove_line]", function(){
44 $("#div_lines").on("click", "button[name=bt_remove_line]", function(){
45 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/delete/";
45 document.location = "/pedestal/{{dev_conf.id}}/line/"+$(this).val()+"/delete/";
46 });
46 });
47
47
48 $("#div_lines").on("click", "button[name=bt_remove_subline]", function(){
48 $("#div_lines").on("click", "button[name=bt_remove_subline]", function(){
@@ -50,22 +50,22
50 });
50 });
51
51
52 $("#div_lines").on("click", "button[name=bt_add_subline]", function(){
52 $("#div_lines").on("click", "button[name=bt_add_subline]", function(){
53 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
53 document.location = "/pedestal/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
54 });
54 });
55
55
56 $("#div_lines").on("click", "button[name=bt_edit_codes]", function(){
56 $("#div_lines").on("click", "button[name=bt_edit_codes]", function(){
57 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/codes/";
57 document.location = "/pedestal/{{dev_conf.id}}/line/"+$(this).val()+"/codes/";
58 });
58 });
59
59
60 $("#bt_add_line").click(function() {
60 $("#bt_add_line").click(function() {
61 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
61 document.location = "{% url 'url_add_pedestal_line' dev_conf.id%}";
62 });
62 });
63
63
64 $(".panel-group").sortable({
64 $(".panel-group").sortable({
65 //placeholder: "ui-state-highlight",
65 //placeholder: "ui-state-highlight",
66 update: function( event, ui ) {
66 update: function( event, ui ) {
67 var sorted = $( ".panel-group" ).sortable( "serialize", { key: "item" } );
67 var sorted = $( ".panel-group" ).sortable( "serialize", { key: "item" } );
68 var url = "{% url 'url_update_rc_lines_position' dev_conf.id %}";
68 var url = "{% url 'url_update_pedestal_lines_position' dev_conf.id %}";
69 var csrf_token = "{{csrf_token}}";
69 var csrf_token = "{{csrf_token}}";
70 $.post( url, { 'items': sorted, 'csrfmiddlewaretoken': csrf_token }, function(data){
70 $.post( url, { 'items': sorted, 'csrfmiddlewaretoken': csrf_token }, function(data){
71 $("#div_lines").html(data.html);
71 $("#div_lines").html(data.html);
@@ -20,7 +20,7
20 });
20 });
21
21
22 $("#id_code").change(function() {
22 $("#id_code").change(function() {
23 var url = "{% url 'url_edit_rc_codes' dev_conf.id line.id %}";
23 var url = "{% url 'url_edit_pedestal_codes' dev_conf.id line.id %}";
24 document.location = url+ $(this).val() + "/";
24 document.location = url+ $(this).val() + "/";
25 });
25 });
26
26
1 NO CONTENT: file renamed from apps/rc/templates/rc_edit_lines.html to apps/pedestal/templates/rc_edit_lines.html
NO CONTENT: file renamed from apps/rc/templates/rc_edit_lines.html to apps/pedestal/templates/rc_edit_lines.html
1 NO CONTENT: file renamed from apps/rc/templates/rc_import.html to apps/pedestal/templates/rc_import.html
NO CONTENT: file renamed from apps/rc/templates/rc_import.html to apps/pedestal/templates/rc_import.html
@@ -21,7 +21,7 Expand/Collapse
21 {% for f in line.subforms %}
21 {% for f in line.subforms %}
22 <div class="form-group form-group-sm">
22 <div class="form-group form-group-sm">
23 <label class="col-md-3 control-label">{{line.line_type.name}}-{{ forloop.counter }}</label>
23 <label class="col-md-3 control-label">{{line.line_type.name}}-{{ forloop.counter }}</label>
24 <div class="col-md-9">{% if edit %}<button type='button' name="bt_remove_subline" class="btn-xs btn-default" data-url="{% url 'url_remove_rc_subline' dev_conf.id line.id forloop.counter %}"><span class="fas fa-times" aria-hidden="true"></span></button>{% endif %}</div>
24 <div class="col-md-9">{% if edit %}<button type='button' name="bt_remove_subline" class="btn-xs btn-default" data-url="{% url 'url_remove_pedestal_subline' dev_conf.id line.id forloop.counter %}"><span class="fas fa-times" aria-hidden="true"></span></button>{% endif %}</div>
25 </div><div class="clearfix"></div>
25 </div><div class="clearfix"></div>
26 {% bootstrap_form f layout='horizontal' size='small' %}
26 {% bootstrap_form f layout='horizontal' size='small' %}
27 <div class="clearfix"></div>
27 <div class="clearfix"></div>
1 NO CONTENT: file renamed from apps/rc/templates/rc_pulses.html to apps/pedestal/templates/rc_pulses.html
NO CONTENT: file renamed from apps/rc/templates/rc_pulses.html to apps/pedestal/templates/rc_pulses.html
1 NO CONTENT: file renamed from apps/rc/tests.py to apps/pedestal/tests.py
NO CONTENT: file renamed from apps/rc/tests.py to apps/pedestal/tests.py
@@ -3,21 +3,21 from django.urls import path
3 from . import views
3 from . import views
4
4
5 urlpatterns = (
5 urlpatterns = (
6 path('<int:conf_id>/', views.conf, name='url_rc_conf'),
6 path('<int:conf_id>/', views.conf, name='url_pedestal_conf'),
7 path('<int:conf_id>/import/', views.import_file, name='url_import_rc_conf'),
7 path('<int:conf_id>/import/', views.import_file, name='url_import_pedestal_conf'),
8 path('<int:conf_id>/edit/', views.conf_edit, name='url_edit_rc_conf'),
8 path('<int:conf_id>/edit/', views.conf_edit, name='url_edit_pedestal_conf'),
9 path('<int:conf_id>/plot/', views.plot_pulses, name='url_plot_rc_pulses'),
9 path('<int:conf_id>/plot/', views.plot_pulses, name='url_plot_pedestal_pulses'),
10 path('<int:conf_id>/plot2/', views.plot_pulses2, name='url_plot_rc_pulses2'),
10 path('<int:conf_id>/plot2/', views.plot_pulses2, name='url_plot_pedestal_pulses2'),
11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
13 path('<int:conf_id>/raw/', views.conf_raw, name='url_raw_rc_conf'),
13 path('<int:conf_id>/raw/', views.conf_raw, name='url_raw_pedestal_conf'),
14 path('<int:conf_id>/add_line/', views.add_line, name='url_add_rc_line'),
14 path('<int:conf_id>/add_line/', views.add_line, name='url_add_pedestal_line'),
15 path('<int:conf_id>/add_line/<int:line_type_id>/', views.add_line, name='url_add_rc_line'),
15 path('<int:conf_id>/add_line/<int:line_type_id>/', views.add_line, name='url_add_pedestal_line'),
16 path('<int:conf_id>/add_line/<int:line_type_id>/code/<int:code_id>/', views.add_line, name='url_add_rc_line_code'),
16 path('<int:conf_id>/add_line/<int:line_type_id>/code/<int:code_id>/', views.add_line, name='url_add_pedestal_line_code'),
17 path('<int:conf_id>/update_position/', views.update_lines_position, name='url_update_rc_lines_position'),
17 path('<int:conf_id>/update_position/', views.update_lines_position, name='url_update_pedestal_lines_position'),
18 path('<int:conf_id>/line/<int:line_id>/delete/', views.remove_line, name='url_remove_rc_line'),
18 path('<int:conf_id>/line/<int:line_id>/delete/', views.remove_line, name='url_remove_pedestal_line'),
19 path('<int:conf_id>/line/<int:line_id>/add_subline/', views.add_subline, name='url_add_rc_subline'),
19 path('<int:conf_id>/line/<int:line_id>/add_subline/', views.add_subline, name='url_add_pedestal_subline'),
20 path('<int:conf_id>/line/<int:line_id>/codes/', views.edit_codes, name='url_edit_rc_codes'),
20 path('<int:conf_id>/line/<int:line_id>/codes/', views.edit_codes, name='url_edit_pedestal_codes'),
21 path('<int:conf_id>/line/<int:line_id>/codes/<int:code_id>/', views.edit_codes, name='url_edit_rc_codes'),
21 path('<int:conf_id>/line/<int:line_id>/codes/<int:code_id>/', views.edit_codes, name='url_edit_pedestal_codes'),
22 path('<int:conf_id>/line/<int:line_id>/subline/<int:subline_id>/delete/', views.remove_subline, name='url_remove_rc_subline'),
22 path('<int:conf_id>/line/<int:line_id>/subline/<int:subline_id>/delete/', views.remove_subline, name='url_remove_pedestal_subline'),
23 )
23 )
@@ -1,243 +1,243
1 '''
1 '''
2 '''
2 '''
3
3
4 import json
4 import json
5
5
6 from apps.main.utils import Params
6 from apps.main.utils import Params
7
7
8 def parse_range(s):
8 def parse_range(s):
9
9
10 vars = ('TXA,', 'A,', 'TXB,', 'B,', 'TXA', 'TXB', 'A', 'B')
10 vars = ('TXA,', 'A,', 'TXB,', 'B,', 'TXA', 'TXB', 'A', 'B')
11
11
12 for var in vars:
12 for var in vars:
13 if var in s:
13 if var in s:
14 s = s.replace(var, '')
14 s = s.replace(var, '')
15 if 'A' in var:
15 if 'A' in var:
16 ref = 'TXA'
16 ref = 'TXA'
17 else:
17 else:
18 ref = 'TXB'
18 ref = 'TXB'
19 return ref, s
19 return ref, s
20
20
21 return '0', s
21 return '0', s
22
22
23
23
24 class RCFile(object):
24 class RCFile(object):
25 '''
25 '''
26 Class to handle Radar controller configuration files
26 Class to handle Radar controller configuration files
27 '''
27 '''
28
28
29 def __init__(self, f=None):
29 def __init__(self, f=None):
30 self.data = {}
30 self.data = {}
31 self.lines = []
31 self.lines = []
32 self.line = ''
32 self.line = ''
33 if isinstance(f, str):
33 if isinstance(f, str):
34 self.f = open(f)
34 self.f = open(f)
35 self.name = f.split('/')[-1]
35 self.name = f.split('/')[-1]
36 elif hasattr(f, 'read'):
36 elif hasattr(f, 'read'):
37 self.f = f
37 self.f = f
38 self.name = f.name.split('/')[-1]
38 self.name = f.name.split('/')[-1]
39 else:
39 else:
40 self.f = f
40 self.f = f
41 self.name = None
41 self.name = None
42
42
43 if self.f:
43 if self.f:
44 if 'racp' in self.name:
44 if 'racp' in self.name:
45 self.parse_racp()
45 self.parse_racp()
46 elif 'dat' in self.name:
46 elif 'dat' in self.name:
47 self.parse_dat()
47 self.parse_dat()
48 elif 'json' in self.name:
48 elif 'json' in self.name:
49 self.data = json.load(self.f)
49 self.data = json.load(self.f)
50
50
51 self.f.close()
51 self.f.close()
52
52
53 def get_line_parameters(self, data, line):
53 def get_line_parameters(self, data, line):
54
54
55 line_params = {}
55 line_params = {}
56 for label in data:
56 for label in data:
57 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
57 if 'L%d' % line in label or '(Line %d)' % line in label or 'Line%d' % line in label:
58 line_params[label] = data[label]
58 line_params[label] = data[label]
59 return line_params
59 return line_params
60
60
61 def parse_racp(self):
61 def parse_racp(self):
62
62
63 data = {}
63 data = {}
64 raw_data = [s.strip() for s in self.f.readlines()]
64 raw_data = [s.strip() for s in self.f.readlines()]
65
65
66 for line in raw_data:
66 for line in raw_data:
67 if line and '=' in line:
67 if line and '=' in line:
68 label, value = line.strip().split('=')
68 label, value = line.strip().split('=')
69 data[label] = value
69 data[label] = value
70
70
71 self.data['id'] = '1'
71 self.data['id'] = '1'
72 self.data['device_type'] = 'rc'
72 self.data['device_type'] = 'pedestal'
73 self.data['experiment_type'] = data['EXPERIMENT TYPE']
73 self.data['experiment_type'] = data['EXPERIMENT TYPE']
74 self.data['header_version'] = data['HEADER VERSION']
74 self.data['header_version'] = data['HEADER VERSION']
75 self.data['label'] = data['EXPERIMENT NAME']
75 self.data['label'] = data['EXPERIMENT NAME']
76 self.data['ipp'] = float(data['IPP'])
76 self.data['ipp'] = float(data['IPP'])
77 self.data['ntx'] = int(data['NTX'])
77 self.data['ntx'] = int(data['NTX'])
78
78
79 if 'CLOCK DIVIDER' in data:
79 if 'CLOCK DIVIDER' in data:
80 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
80 self.data['clock_divider'] = int(data['CLOCK DIVIDER'])
81 else:
81 else:
82 self.data['clock_divider'] = 1
82 self.data['clock_divider'] = 1
83 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
83 self.data['clock_in'] = float(data['RELOJ'])*self.data['clock_divider']
84 self.data['clock'] = float(data['RELOJ'])
84 self.data['clock'] = float(data['RELOJ'])
85 self.data['time_before'] = int(data['TR_BEFORE'])
85 self.data['time_before'] = int(data['TR_BEFORE'])
86 self.data['time_after'] = int(data['TR_AFTER'])
86 self.data['time_after'] = int(data['TR_AFTER'])
87
87
88 if 'SYNCHRO DELAY' in data:
88 if 'SYNCHRO DELAY' in data:
89 self.data['sync'] = int(data['SYNCHRO DELAY'])
89 self.data['sync'] = int(data['SYNCHRO DELAY'])
90 else:
90 else:
91 self.data['sync'] = 0
91 self.data['sync'] = 0
92
92
93 self.data['lines'] = []
93 self.data['lines'] = []
94
94
95 if 'SAMPLING REFERENCE' in data:
95 if 'SAMPLING REFERENCE' in data:
96 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
96 if data['SAMPLING REFERENCE']=='MIDDLE OF FIRST BAUD':
97 self.data['sampling_reference'] = 'first_baud'
97 self.data['sampling_reference'] = 'first_baud'
98 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
98 elif data['SAMPLING REFERENCE']=='MIDDLE OF FIRST SUB-BAUD':
99 self.data['sampling_reference'] = 'sub_baud'
99 self.data['sampling_reference'] = 'sub_baud'
100 else:
100 else:
101 self.data['sampling_reference'] = 'none'
101 self.data['sampling_reference'] = 'none'
102
102
103 self.data['lines'].append('10')
103 self.data['lines'].append('10')
104
104
105 #Add TX's lines
105 #Add TX's lines
106 if 'TXA' in data:
106 if 'TXA' in data:
107 line = {'line_type':'tx', 'id':'11', 'name':'TXA',
107 line = {'line_type':'tx', 'id':'11', 'name':'TXA',
108 'params':{'pulse_width':data['TXA'], 'delays':'0', 'range':'0'}}
108 'params':{'pulse_width':data['TXA'], 'delays':'0', 'range':'0'}}
109 if 'Pulse selection_TXA' in data:
109 if 'Pulse selection_TXA' in data:
110 line['params']['range'] = data['Pulse selection_TXA']
110 line['params']['range'] = data['Pulse selection_TXA']
111 self.data['lines'].append('11')
111 self.data['lines'].append('11')
112 self.lines.append(line)
112 self.lines.append(line)
113
113
114 if 'TXB' in data:
114 if 'TXB' in data:
115 line = {'line_type':'tx', 'id':'12', 'name':'TXB',
115 line = {'line_type':'tx', 'id':'12', 'name':'TXB',
116 'params':{'pulse_width':data['TXB'], 'delays':'0', 'range':'0'}}
116 'params':{'pulse_width':data['TXB'], 'delays':'0', 'range':'0'}}
117 if 'Pulse selection_TXB' in data:
117 if 'Pulse selection_TXB' in data:
118 line['params']['range'] = data['Pulse selection_TXB']
118 line['params']['range'] = data['Pulse selection_TXB']
119
119
120 if 'Number of Taus' in data:
120 if 'Number of Taus' in data:
121 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
121 delays = [data['TAU({0})'.format(i)] for i in range(int(data['Number of Taus']))]
122 line['params']['delays'] = ','.join(delays)
122 line['params']['delays'] = ','.join(delays)
123
123
124 self.data['lines'].append('12')
124 self.data['lines'].append('12')
125 self.lines.append(line)
125 self.lines.append(line)
126
126
127 #Add TR line
127 #Add TR line
128 line = {'line_type':'tr', 'id':'10', 'name':'TR',
128 line = {'line_type':'tr', 'id':'10', 'name':'TR',
129 'params':{'TX_ref':'0', 'range':'0'}}
129 'params':{'TX_ref':'0', 'range':'0'}}
130 if 'Pulse selection_TR' in data:
130 if 'Pulse selection_TR' in data:
131 ref, rng = parse_range(data['Pulse selection_TR'])
131 ref, rng = parse_range(data['Pulse selection_TR'])
132 line['params']['range'] = rng if rng else '0'
132 line['params']['range'] = rng if rng else '0'
133 if ref=='TXA':
133 if ref=='TXA':
134 line['params']['TX_ref'] = '11'
134 line['params']['TX_ref'] = '11'
135 elif ref=='TXB':
135 elif ref=='TXB':
136 line['params']['TX_ref'] = '12'
136 line['params']['TX_ref'] = '12'
137
137
138 self.lines.append(line)
138 self.lines.append(line)
139
139
140 #Add Other lines (4-6)
140 #Add Other lines (4-6)
141 for n in range(4, 7):
141 for n in range(4, 7):
142 id = '{:2d}'.format(10*n)
142 id = '{:2d}'.format(10*n)
143 params = self.get_line_parameters(data, n)
143 params = self.get_line_parameters(data, n)
144 labels = params.keys()
144 labels = params.keys()
145
145
146 if 'L%d_FLIP' % n in labels:
146 if 'L%d_FLIP' % n in labels:
147 line = {'line_type':'flip', 'id':id,
147 line = {'line_type':'flip', 'id':id,
148 'params':{'number_of_flips':data['L%d_FLIP' % n]}}
148 'params':{'number_of_flips':data['L%d_FLIP' % n]}}
149 elif 'Code Type' in data and n==4:
149 elif 'Code Type' in data and n==4:
150 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type']}}
150 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type']}}
151 if data['L%d_REFERENCE' % n]=='TXA':
151 if data['L%d_REFERENCE' % n]=='TXA':
152 line['params']['TX_ref'] = '11'
152 line['params']['TX_ref'] = '11'
153 else:
153 else:
154 line['params']['TX_ref'] = '12'
154 line['params']['TX_ref'] = '12'
155 if 'Number of Codes' in data:
155 if 'Number of Codes' in data:
156 line['params']['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
156 line['params']['codes'] = [data['COD({})'.format(x)] for x in range(int(data['Number of Codes']))]
157 elif 'Code Type (Line %d)' % n in labels:
157 elif 'Code Type (Line %d)' % n in labels:
158 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type (Line %d)' % n]}}
158 line = {'line_type':'codes', 'id':id, 'params':{'code':data['Code Type (Line %d)' % n]}}
159 if data['L%d_REFERENCE' % n]=='TXA':
159 if data['L%d_REFERENCE' % n]=='TXA':
160 line['params']['TX_ref'] = '11'
160 line['params']['TX_ref'] = '11'
161 else:
161 else:
162 line['params']['TX_ref'] = '12'
162 line['params']['TX_ref'] = '12'
163 if 'Number of Codes (Line %d)' % n in data:
163 if 'Number of Codes (Line %d)' % n in data:
164 line['params']['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
164 line['params']['codes'] = [data['L{}_COD({})'.format(n, x)] for x in range(int(data['Number of Codes (Line %d)' % n]))]
165 elif 'Sampling Windows (Line %d)' % n in data:
165 elif 'Sampling Windows (Line %d)' % n in data:
166 line = {'line_type':'windows', 'id':id, 'params':{}}
166 line = {'line_type':'windows', 'id':id, 'params':{}}
167 if data['L%d_REFERENCE' % n]=='TXA':
167 if data['L%d_REFERENCE' % n]=='TXA':
168 line['params']['TX_ref'] = '11'
168 line['params']['TX_ref'] = '11'
169 else:
169 else:
170 line['params']['TX_ref'] = '12'
170 line['params']['TX_ref'] = '12'
171 windows = []
171 windows = []
172 for w in range(int(data['Sampling Windows (Line %d)' % n])):
172 for w in range(int(data['Sampling Windows (Line %d)' % n])):
173 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
173 windows.append({'first_height':float(data['L%d_H0(%d)' % (n, w)]),
174 'resolution':float(data['L%d_DH(%d)' % (n, w)]),
174 'resolution':float(data['L%d_DH(%d)' % (n, w)]),
175 'number_of_samples':int(float(data['L%d_NSA(%d)' % (n, w)])),
175 'number_of_samples':int(float(data['L%d_NSA(%d)' % (n, w)])),
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)])
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)])
177 }
177 }
178 )
178 )
179 line['params']['params'] = windows
179 line['params']['params'] = windows
180 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
180 elif 'Line%d' % n in labels and data['Line%d' % n]=='Synchro':
181 line = {'line_type':'sync', 'id':id, 'params':{'invert':0}}
181 line = {'line_type':'sync', 'id':id, 'params':{'invert':0}}
182 elif 'L%d Number Of Portions' % n in labels:
182 elif 'L%d Number Of Portions' % n in labels:
183 line = {'line_type':'prog_pulses', 'id':id, 'params':{}}
183 line = {'line_type':'prog_pulses', 'id':id, 'params':{}}
184 if 'L%s Portions IPP Periodic' % n in data:
184 if 'L%s Portions IPP Periodic' % n in data:
185 line['params']['periodic'] = '1' if data['L%s Portions IPP Periodic' % n]=='YES' else '0'
185 line['params']['periodic'] = '1' if data['L%s Portions IPP Periodic' % n]=='YES' else '0'
186 portions = []
186 portions = []
187 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
187 x = raw_data.index('L%d Number Of Portions=%s' % (n, data['L%d Number Of Portions' % n]))
188 for w in range(int(data['L%d Number Of Portions' % n])):
188 for w in range(int(data['L%d Number Of Portions' % n])):
189 begin = float(raw_data[x+1+2*w].split('=')[-1])
189 begin = float(raw_data[x+1+2*w].split('=')[-1])
190 end = float(raw_data[x+2+2*w].split('=')[-1])
190 end = float(raw_data[x+2+2*w].split('=')[-1])
191 portions.append({'begin':int(begin),
191 portions.append({'begin':int(begin),
192 'end':int(end)}
192 'end':int(end)}
193 )
193 )
194 line['params']['params'] = portions
194 line['params']['params'] = portions
195 elif 'FLIP1' in data and n==5:
195 elif 'FLIP1' in data and n==5:
196 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP1']}}
196 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP1']}}
197 elif 'FLIP2' in data and n==6:
197 elif 'FLIP2' in data and n==6:
198 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP2']}}
198 line = {'line_type':'flip', 'id':id, 'params':{'number_of_flips':data['FLIP2']}}
199 else:
199 else:
200 line = {'line_type':'none', 'id':id, 'params':{}}
200 line = {'line_type':'none', 'id':id, 'params':{}}
201
201
202 self.data['lines'].append(id)
202 self.data['lines'].append(id)
203 self.lines.append(line)
203 self.lines.append(line)
204
204
205 #Add line 7 (windows)
205 #Add line 7 (windows)
206 if 'Sampling Windows' in data:
206 if 'Sampling Windows' in data:
207 line = {'line_type':'windows', 'id':'17', 'params':{}}
207 line = {'line_type':'windows', 'id':'17', 'params':{}}
208 if data['L7_REFERENCE']=='TXA':
208 if data['L7_REFERENCE']=='TXA':
209 line['params']['TX_ref'] = '11'
209 line['params']['TX_ref'] = '11'
210 else:
210 else:
211 line['params']['TX_ref'] = '12'
211 line['params']['TX_ref'] = '12'
212 windows = []
212 windows = []
213 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
213 x = raw_data.index('Sampling Windows=%s' % data['Sampling Windows'])
214 for w in range(int(data['Sampling Windows'])):
214 for w in range(int(data['Sampling Windows'])):
215 h0 = raw_data[x+1+3*w].split('=')[-1]
215 h0 = raw_data[x+1+3*w].split('=')[-1]
216 nsa = raw_data[x+2+3*w].split('=')[-1]
216 nsa = raw_data[x+2+3*w].split('=')[-1]
217 dh = raw_data[x+3+3*w].split('=')[-1]
217 dh = raw_data[x+3+3*w].split('=')[-1]
218 windows.append({'first_height':float(h0),
218 windows.append({'first_height':float(h0),
219 'number_of_samples':int(nsa),
219 'number_of_samples':int(nsa),
220 'resolution':float(dh),
220 'resolution':float(dh),
221 'last_height':float(h0)+float(dh)*(int(nsa)-1)}
221 'last_height':float(h0)+float(dh)*(int(nsa)-1)}
222 )
222 )
223 line['params']['params'] = windows
223 line['params']['params'] = windows
224 self.data['lines'].append('17')
224 self.data['lines'].append('17')
225 self.lines.append(line)
225 self.lines.append(line)
226
226
227 #Add line 8 (synchro inverted)
227 #Add line 8 (synchro inverted)
228 self.data['lines'].append('18')
228 self.data['lines'].append('18')
229 self.lines.append({'line_type':'sync', 'id':'18', 'params':{'invert':1}})
229 self.lines.append({'line_type':'sync', 'id':'18', 'params':{'invert':1}})
230
230
231 return
231 return
232
232
233 def parse_dat(self):
233 def parse_dat(self):
234 pass
234 pass
235
235
236 def to_dict(self):
236 def to_dict(self):
237
237
238 out = Params()
238 out = Params()
239 out.add(self.data, 'configurations')
239 out.add(self.data, 'configurations')
240 for line_data in self.lines:
240 for line_data in self.lines:
241 out.add(line_data, 'lines')
241 out.add(line_data, 'lines')
242
242
243 return out.data
243 return out.data
@@ -33,9 +33,7 def conf(request, conf_id):
33 kwargs['clock'] = clk
33 kwargs['clock'] = clk
34 kwargs['dev_conf'] = conf
34 kwargs['dev_conf'] = conf
35 kwargs['rc_lines'] = lines
35 kwargs['rc_lines'] = lines
36 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
36 kwargs['dev_conf_keys'] = ['axis', 'speed', 'table']
37 'time_before', 'time_after', 'sync', 'sampling_reference',
38 'control_tx', 'control_sw']
39
37
40 kwargs['title'] = 'Configuration'
38 kwargs['title'] = 'Configuration'
41 kwargs['suptitle'] = 'Detail'
39 kwargs['suptitle'] = 'Detail'
@@ -160,6 +158,8 def conf_edit(request, conf_id):
160 kwargs['suptitle'] = 'Edit'
158 kwargs['suptitle'] = 'Edit'
161 kwargs['button'] = 'Update'
159 kwargs['button'] = 'Update'
162
160
161 print(kwargs)
162 print(form)
163 return render(request, 'rc_conf_edit.html', kwargs)
163 return render(request, 'rc_conf_edit.html', kwargs)
164
164
165
165
@@ -190,7 +190,7 def add_line(request, conf_id, line_type_id=None, code_id=None):
190 if form.is_valid():
190 if form.is_valid():
191 form.save()
191 form.save()
192 form.instance.update_pulses()
192 form.instance.update_pulses()
193 return redirect('url_edit_rc_conf', conf.id)
193 return redirect('url_edit_pedestal_conf', conf.id)
194
194
195 kwargs = {}
195 kwargs = {}
196 kwargs['form'] = form
196 kwargs['form'] = form
1 NO CONTENT: file renamed from apps/rc/widgets.py to apps/pedestal/widgets.py
NO CONTENT: file renamed from apps/rc/widgets.py to apps/pedestal/widgets.py
1 NO CONTENT: file renamed from apps/rc/migrations/__init__.py to apps/usrp(antes)/__init__.py
NO CONTENT: file renamed from apps/rc/migrations/__init__.py to apps/usrp(antes)/__init__.py
1 NO CONTENT: file renamed from apps/usrp/admin.py to apps/usrp(antes)/admin.py
NO CONTENT: file renamed from apps/usrp/admin.py to apps/usrp(antes)/admin.py
1 NO CONTENT: file renamed from apps/usrp/forms.py to apps/usrp(antes)/forms.py
NO CONTENT: file renamed from apps/usrp/forms.py to apps/usrp(antes)/forms.py
@@ -4,6 +4,11 from apps.main.models import Configuration
4
4
5 class USRPConfiguration(Configuration):
5 class USRPConfiguration(Configuration):
6
6
7 frequency = models.FloatField(
8 verbose_name='Frequency (MHz)',
9 blank=False,
10 null=False
11 )
7
12
8 class Meta:
13 class Meta:
9 db_table = 'usrp_configurations'
14 db_table = 'usrp_configurations'
1 NO CONTENT: file renamed from apps/usrp/tests.py to apps/usrp(antes)/tests.py
NO CONTENT: file renamed from apps/usrp/tests.py to apps/usrp(antes)/tests.py
1 NO CONTENT: file renamed from apps/usrp/urls.py to apps/usrp(antes)/urls.py
NO CONTENT: file renamed from apps/usrp/urls.py to apps/usrp(antes)/urls.py
1 NO CONTENT: file renamed from apps/usrp/views.py to apps/usrp(antes)/views.py
NO CONTENT: file renamed from apps/usrp/views.py to apps/usrp(antes)/views.py
1 NO CONTENT: file renamed from apps/usrp/__init__.py to apps/usrp_rx/__init__.py
NO CONTENT: file renamed from apps/usrp/__init__.py to apps/usrp_rx/__init__.py
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now