##// END OF EJS Templates
Merge remote-tracking branch 'upstream/master'
Doug Blank -
r15207:16945929 merge
parent child Browse files
Show More

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

@@ -0,0 +1,251 b''
1 """Interact with functions using widgets."""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 from __future__ import print_function
16
17 try: # Python >= 3.3
18 from inspect import signature, Parameter
19 except ImportError:
20 from IPython.utils.signatures import signature, Parameter
21 from inspect import getcallargs
22
23 from IPython.html.widgets import (Widget, TextWidget,
24 FloatSliderWidget, IntSliderWidget, CheckboxWidget, DropdownWidget,
25 ContainerWidget, DOMWidget)
26 from IPython.display import display, clear_output
27 from IPython.utils.py3compat import string_types, unicode_type
28 from IPython.utils.traitlets import HasTraits, Any, Unicode
29
30 #-----------------------------------------------------------------------------
31 # Classes and Functions
32 #-----------------------------------------------------------------------------
33
34
35 def _matches(o, pattern):
36 """Match a pattern of types in a sequence."""
37 if not len(o) == len(pattern):
38 return False
39 comps = zip(o,pattern)
40 return all(isinstance(obj,kind) for obj,kind in comps)
41
42
43 def _get_min_max_value(min, max, value=None, step=None):
44 """Return min, max, value given input values with possible None."""
45 if value is None:
46 if not max > min:
47 raise ValueError('max must be greater than min: (min={0}, max={1})'.format(min, max))
48 value = min + abs(min-max)/2
49 value = type(min)(value)
50 elif min is None and max is None:
51 if value == 0.0:
52 min, max, value = 0.0, 1.0, 0.5
53 elif value == 0:
54 min, max, value = 0, 1, 0
55 elif isinstance(value, (int, float)):
56 min, max = (-value, 3*value) if value > 0 else (3*value, -value)
57 else:
58 raise TypeError('expected a number, got: %r' % value)
59 else:
60 raise ValueError('unable to infer range, value from: ({0}, {1}, {2})'.format(min, max, value))
61 if step is not None:
62 # ensure value is on a step
63 r = (value - min) % step
64 value = value - r
65 return min, max, value
66
67 def _widget_abbrev_single_value(o):
68 """Make widgets from single values, which can be used as parameter defaults."""
69 if isinstance(o, string_types):
70 return TextWidget(value=unicode_type(o))
71 elif isinstance(o, dict):
72 return DropdownWidget(values=o)
73 elif isinstance(o, bool):
74 return CheckboxWidget(value=o)
75 elif isinstance(o, float):
76 min, max, value = _get_min_max_value(None, None, o)
77 return FloatSliderWidget(value=o, min=min, max=max)
78 elif isinstance(o, int):
79 min, max, value = _get_min_max_value(None, None, o)
80 return IntSliderWidget(value=o, min=min, max=max)
81 else:
82 return None
83
84 def _widget_abbrev(o):
85 """Make widgets from abbreviations: single values, lists or tuples."""
86 float_or_int = (float, int)
87 if isinstance(o, (list, tuple)):
88 if o and all(isinstance(x, string_types) for x in o):
89 return DropdownWidget(values=[unicode_type(k) for k in o])
90 elif _matches(o, (float_or_int, float_or_int)):
91 min, max, value = _get_min_max_value(o[0], o[1])
92 if all(isinstance(_, int) for _ in o):
93 cls = IntSliderWidget
94 else:
95 cls = FloatSliderWidget
96 return cls(value=value, min=min, max=max)
97 elif _matches(o, (float_or_int, float_or_int, float_or_int)):
98 step = o[2]
99 if step <= 0:
100 raise ValueError("step must be >= 0, not %r" % step)
101 min, max, value = _get_min_max_value(o[0], o[1], step=step)
102 if all(isinstance(_, int) for _ in o):
103 cls = IntSliderWidget
104 else:
105 cls = FloatSliderWidget
106 return cls(value=value, min=min, max=max, step=step)
107 else:
108 return _widget_abbrev_single_value(o)
109
110 def _widget_from_abbrev(abbrev):
111 """Build a Widget intstance given an abbreviation or Widget."""
112 if isinstance(abbrev, Widget) or isinstance(abbrev, fixed):
113 return abbrev
114
115 widget = _widget_abbrev(abbrev)
116 if widget is None:
117 raise ValueError("%r cannot be transformed to a Widget" % (abbrev,))
118 return widget
119
120 def _yield_abbreviations_for_parameter(param, kwargs):
121 """Get an abbreviation for a function parameter."""
122 name = param.name
123 kind = param.kind
124 ann = param.annotation
125 default = param.default
126 empty = Parameter.empty
127 not_found = (None, None)
128 if kind == Parameter.POSITIONAL_OR_KEYWORD:
129 if name in kwargs:
130 yield name, kwargs.pop(name)
131 elif ann is not empty:
132 if default is empty:
133 yield name, ann
134 else:
135 yield name, ann
136 elif default is not empty:
137 yield name, default
138 else:
139 yield not_found
140 elif kind == Parameter.KEYWORD_ONLY:
141 if name in kwargs:
142 yield name, kwargs.pop(name)
143 elif ann is not empty:
144 yield name, ann
145 elif default is not empty:
146 yield name, default
147 else:
148 yield not_found
149 elif kind == Parameter.VAR_KEYWORD:
150 # In this case name=kwargs and we yield the items in kwargs with their keys.
151 for k, v in kwargs.copy().items():
152 kwargs.pop(k)
153 yield k, v
154
155 def _find_abbreviations(f, kwargs):
156 """Find the abbreviations for a function and kwargs passed to interact."""
157 new_kwargs = []
158 for param in signature(f).parameters.values():
159 for name, value in _yield_abbreviations_for_parameter(param, kwargs):
160 if value is None:
161 raise ValueError('cannot find widget or abbreviation for argument: {!r}'.format(name))
162 new_kwargs.append((name, value))
163 return new_kwargs
164
165 def _widgets_from_abbreviations(seq):
166 """Given a sequence of (name, abbrev) tuples, return a sequence of Widgets."""
167 result = []
168 for name, abbrev in seq:
169 widget = _widget_from_abbrev(abbrev)
170 widget.description = name
171 result.append(widget)
172 return result
173
174 def interactive(__interact_f, **kwargs):
175 """Build a group of widgets to interact with a function."""
176 f = __interact_f
177 co = kwargs.pop('clear_output', True)
178 kwargs_widgets = []
179 container = ContainerWidget()
180 container.result = None
181 container.args = []
182 container.kwargs = dict()
183 kwargs = kwargs.copy()
184
185 new_kwargs = _find_abbreviations(f, kwargs)
186 # Before we proceed, let's make sure that the user has passed a set of args+kwargs
187 # that will lead to a valid call of the function. This protects against unspecified
188 # and doubly-specified arguments.
189 getcallargs(f, **{n:v for n,v in new_kwargs})
190 # Now build the widgets from the abbreviations.
191 kwargs_widgets.extend(_widgets_from_abbreviations(new_kwargs))
192 kwargs_widgets.extend(_widgets_from_abbreviations(sorted(kwargs.items(), key = lambda x: x[0])))
193
194 # This has to be done as an assignment, not using container.children.append,
195 # so that traitlets notices the update. We skip any objects (such as fixed) that
196 # are not DOMWidgets.
197 c = [w for w in kwargs_widgets if isinstance(w, DOMWidget)]
198 container.children = c
199
200 # Build the callback
201 def call_f(name, old, new):
202 container.kwargs = {}
203 for widget in kwargs_widgets:
204 value = widget.value
205 container.kwargs[widget.description] = value
206 if co:
207 clear_output(wait=True)
208 container.result = f(**container.kwargs)
209
210 # Wire up the widgets
211 for widget in kwargs_widgets:
212 widget.on_trait_change(call_f, 'value')
213
214 container.on_displayed(lambda _: call_f(None, None, None))
215
216 return container
217
218 def interact(__interact_f=None, **kwargs):
219 """interact(f, **kwargs)
220
221 Interact with a function using widgets."""
222 # positional arg support in: https://gist.github.com/8851331
223 if __interact_f is not None:
224 # This branch handles the cases:
225 # 1. interact(f, **kwargs)
226 # 2. @interact
227 # def f(*args, **kwargs):
228 # ...
229 f = __interact_f
230 w = interactive(f, **kwargs)
231 f.widget = w
232 display(w)
233 return f
234 else:
235 # This branch handles the case:
236 # @interact(a=30, b=40)
237 # def f(*args, **kwargs):
238 # ...
239 def dec(f):
240 w = interactive(f, **kwargs)
241 f.widget = w
242 display(w)
243 return f
244 return dec
245
246 class fixed(HasTraits):
247 """A pseudo-widget whose value is fixed and never synced to the client."""
248 value = Any(help="Any Python object")
249 description = Unicode('', help="Any Python object")
250 def __init__(self, value, **kwargs):
251 super(fixed, self).__init__(value=value, **kwargs)
1 NO CONTENT: new file 100644
@@ -0,0 +1,408 b''
1 """Test interact and interactive."""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2014 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 from __future__ import print_function
15
16 from collections import OrderedDict
17
18 import nose.tools as nt
19 import IPython.testing.tools as tt
20
21 # from IPython.core.getipython import get_ipython
22 from IPython.html import widgets
23 from IPython.html.widgets import interact, interactive, Widget, interaction
24 from IPython.utils.py3compat import annotate
25 # from IPython.utils.capture import capture_output
26
27 #-----------------------------------------------------------------------------
28 # Utility stuff
29 #-----------------------------------------------------------------------------
30
31 class DummyComm(object):
32 comm_id = 'a-b-c-d'
33 def send(self, *args, **kwargs):
34 pass
35
36 def close(self, *args, **kwargs):
37 pass
38
39 _widget_attrs = {}
40 displayed = []
41
42 def setup():
43 _widget_attrs['comm'] = Widget.comm
44 Widget.comm = DummyComm()
45 _widget_attrs['_ipython_display_'] = Widget._ipython_display_
46 def raise_not_implemented(*args, **kwargs):
47 raise NotImplementedError()
48 Widget._ipython_display_ = raise_not_implemented
49
50 def teardown():
51 for attr, value in _widget_attrs.items():
52 setattr(Widget, attr, value)
53
54 def f(**kwargs):
55 pass
56
57 def clear_display():
58 global displayed
59 displayed = []
60
61 def record_display(*args):
62 displayed.extend(args)
63
64 #-----------------------------------------------------------------------------
65 # Actual tests
66 #-----------------------------------------------------------------------------
67
68 def check_widget(w, **d):
69 """Check a single widget against a dict"""
70 for attr, expected in d.items():
71 if attr == 'cls':
72 nt.assert_is(w.__class__, expected)
73 else:
74 value = getattr(w, attr)
75 nt.assert_equal(value, expected,
76 "%s.%s = %r != %r" % (w.__class__.__name__, attr, value, expected)
77 )
78
79 def check_widgets(container, **to_check):
80 """Check that widgets are created as expected"""
81 # build a widget dictionary, so it matches
82 widgets = {}
83 for w in container.children:
84 widgets[w.description] = w
85
86 for key, d in to_check.items():
87 nt.assert_in(key, widgets)
88 check_widget(widgets[key], **d)
89
90
91 def test_single_value_string():
92 a = u'hello'
93 c = interactive(f, a=a)
94 w = c.children[0]
95 check_widget(w,
96 cls=widgets.TextWidget,
97 description='a',
98 value=a,
99 )
100
101 def test_single_value_bool():
102 for a in (True, False):
103 c = interactive(f, a=a)
104 w = c.children[0]
105 check_widget(w,
106 cls=widgets.CheckboxWidget,
107 description='a',
108 value=a,
109 )
110
111 def test_single_value_dict():
112 for d in [
113 dict(a=5),
114 dict(a=5, b='b', c=dict),
115 ]:
116 c = interactive(f, d=d)
117 w = c.children[0]
118 check_widget(w,
119 cls=widgets.DropdownWidget,
120 description='d',
121 values=d,
122 value=next(iter(d.values())),
123 )
124
125 def test_single_value_float():
126 for a in (2.25, 1.0, -3.5):
127 c = interactive(f, a=a)
128 w = c.children[0]
129 check_widget(w,
130 cls=widgets.FloatSliderWidget,
131 description='a',
132 value=a,
133 min= -a if a > 0 else 3*a,
134 max= 3*a if a > 0 else -a,
135 step=0.1,
136 readout=True,
137 )
138
139 def test_single_value_int():
140 for a in (1, 5, -3):
141 c = interactive(f, a=a)
142 nt.assert_equal(len(c.children), 1)
143 w = c.children[0]
144 check_widget(w,
145 cls=widgets.IntSliderWidget,
146 description='a',
147 value=a,
148 min= -a if a > 0 else 3*a,
149 max= 3*a if a > 0 else -a,
150 step=1,
151 readout=True,
152 )
153
154 def test_list_tuple_2_int():
155 with nt.assert_raises(ValueError):
156 c = interactive(f, tup=(1,1))
157 with nt.assert_raises(ValueError):
158 c = interactive(f, tup=(1,-1))
159 for min, max in [ (0,1), (1,10), (1,2), (-5,5), (-20,-19) ]:
160 c = interactive(f, tup=(min, max), lis=[min, max])
161 nt.assert_equal(len(c.children), 2)
162 d = dict(
163 cls=widgets.IntSliderWidget,
164 min=min,
165 max=max,
166 step=1,
167 readout=True,
168 )
169 check_widgets(c, tup=d, lis=d)
170
171 def test_list_tuple_3_int():
172 with nt.assert_raises(ValueError):
173 c = interactive(f, tup=(1,2,0))
174 with nt.assert_raises(ValueError):
175 c = interactive(f, tup=(1,2,-1))
176 for min, max, step in [ (0,2,1), (1,10,2), (1,100,2), (-5,5,4), (-100,-20,4) ]:
177 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
178 nt.assert_equal(len(c.children), 2)
179 d = dict(
180 cls=widgets.IntSliderWidget,
181 min=min,
182 max=max,
183 step=step,
184 readout=True,
185 )
186 check_widgets(c, tup=d, lis=d)
187
188 def test_list_tuple_2_float():
189 with nt.assert_raises(ValueError):
190 c = interactive(f, tup=(1.0,1.0))
191 with nt.assert_raises(ValueError):
192 c = interactive(f, tup=(0.5,-0.5))
193 for min, max in [ (0.5, 1.5), (1.1,10.2), (1,2.2), (-5.,5), (-20,-19.) ]:
194 c = interactive(f, tup=(min, max), lis=[min, max])
195 nt.assert_equal(len(c.children), 2)
196 d = dict(
197 cls=widgets.FloatSliderWidget,
198 min=min,
199 max=max,
200 step=.1,
201 readout=True,
202 )
203 check_widgets(c, tup=d, lis=d)
204
205 def test_list_tuple_3_float():
206 with nt.assert_raises(ValueError):
207 c = interactive(f, tup=(1,2,0.0))
208 with nt.assert_raises(ValueError):
209 c = interactive(f, tup=(-1,-2,1.))
210 with nt.assert_raises(ValueError):
211 c = interactive(f, tup=(1,2.,-1.))
212 for min, max, step in [ (0.,2,1), (1,10.,2), (1,100,2.), (-5.,5.,4), (-100,-20.,4.) ]:
213 c = interactive(f, tup=(min, max, step), lis=[min, max, step])
214 nt.assert_equal(len(c.children), 2)
215 d = dict(
216 cls=widgets.FloatSliderWidget,
217 min=min,
218 max=max,
219 step=step,
220 readout=True,
221 )
222 check_widgets(c, tup=d, lis=d)
223
224 def test_list_tuple_str():
225 values = ['hello', 'there', 'guy']
226 first = values[0]
227 dvalues = OrderedDict((v,v) for v in values)
228 c = interactive(f, tup=tuple(values), lis=list(values))
229 nt.assert_equal(len(c.children), 2)
230 d = dict(
231 cls=widgets.DropdownWidget,
232 value=first,
233 values=dvalues
234 )
235 check_widgets(c, tup=d, lis=d)
236
237 def test_list_tuple_invalid():
238 for bad in [
239 (),
240 (5, 'hi'),
241 ('hi', 5),
242 ({},),
243 (None,),
244 ]:
245 with nt.assert_raises(ValueError):
246 print(bad) # because there is no custom message in assert_raises
247 c = interactive(f, tup=bad)
248
249 def test_defaults():
250 @annotate(n=10)
251 def f(n, f=4.5):
252 pass
253
254 c = interactive(f)
255 check_widgets(c,
256 n=dict(
257 cls=widgets.IntSliderWidget,
258 value=10,
259 ),
260 f=dict(
261 cls=widgets.FloatSliderWidget,
262 value=4.5,
263 ),
264 )
265
266 def test_annotations():
267 @annotate(n=10, f=widgets.FloatTextWidget())
268 def f(n, f):
269 pass
270
271 c = interactive(f)
272 check_widgets(c,
273 n=dict(
274 cls=widgets.IntSliderWidget,
275 value=10,
276 ),
277 f=dict(
278 cls=widgets.FloatTextWidget,
279 ),
280 )
281
282 def test_priority():
283 @annotate(annotate='annotate', kwarg='annotate')
284 def f(kwarg='default', annotate='default', default='default'):
285 pass
286
287 c = interactive(f, kwarg='kwarg')
288 check_widgets(c,
289 kwarg=dict(
290 cls=widgets.TextWidget,
291 value='kwarg',
292 ),
293 annotate=dict(
294 cls=widgets.TextWidget,
295 value='annotate',
296 ),
297 )
298
299 @nt.with_setup(clear_display)
300 def test_decorator_kwarg():
301 with tt.monkeypatch(interaction, 'display', record_display):
302 @interact(a=5)
303 def foo(a):
304 pass
305 nt.assert_equal(len(displayed), 1)
306 w = displayed[0].children[0]
307 check_widget(w,
308 cls=widgets.IntSliderWidget,
309 value=5,
310 )
311
312 @nt.with_setup(clear_display)
313 def test_decorator_no_call():
314 with tt.monkeypatch(interaction, 'display', record_display):
315 @interact
316 def foo(a='default'):
317 pass
318 nt.assert_equal(len(displayed), 1)
319 w = displayed[0].children[0]
320 check_widget(w,
321 cls=widgets.TextWidget,
322 value='default',
323 )
324
325 @nt.with_setup(clear_display)
326 def test_call_interact():
327 def foo(a='default'):
328 pass
329 with tt.monkeypatch(interaction, 'display', record_display):
330 ifoo = interact(foo)
331 nt.assert_equal(len(displayed), 1)
332 w = displayed[0].children[0]
333 check_widget(w,
334 cls=widgets.TextWidget,
335 value='default',
336 )
337
338 @nt.with_setup(clear_display)
339 def test_call_interact_kwargs():
340 def foo(a='default'):
341 pass
342 with tt.monkeypatch(interaction, 'display', record_display):
343 ifoo = interact(foo, a=10)
344 nt.assert_equal(len(displayed), 1)
345 w = displayed[0].children[0]
346 check_widget(w,
347 cls=widgets.IntSliderWidget,
348 value=10,
349 )
350
351 @nt.with_setup(clear_display)
352 def test_call_decorated_on_trait_change():
353 """test calling @interact decorated functions"""
354 d = {}
355 with tt.monkeypatch(interaction, 'display', record_display):
356 @interact
357 def foo(a='default'):
358 d['a'] = a
359 return a
360 nt.assert_equal(len(displayed), 1)
361 w = displayed[0].children[0]
362 check_widget(w,
363 cls=widgets.TextWidget,
364 value='default',
365 )
366 # test calling the function directly
367 a = foo('hello')
368 nt.assert_equal(a, 'hello')
369 nt.assert_equal(d['a'], 'hello')
370
371 # test that setting trait values calls the function
372 w.value = 'called'
373 nt.assert_equal(d['a'], 'called')
374
375 @nt.with_setup(clear_display)
376 def test_call_decorated_kwargs_on_trait_change():
377 """test calling @interact(foo=bar) decorated functions"""
378 d = {}
379 with tt.monkeypatch(interaction, 'display', record_display):
380 @interact(a='kwarg')
381 def foo(a='default'):
382 d['a'] = a
383 return a
384 nt.assert_equal(len(displayed), 1)
385 w = displayed[0].children[0]
386 check_widget(w,
387 cls=widgets.TextWidget,
388 value='kwarg',
389 )
390 # test calling the function directly
391 a = foo('hello')
392 nt.assert_equal(a, 'hello')
393 nt.assert_equal(d['a'], 'hello')
394
395 # test that setting trait values calls the function
396 w.value = 'called'
397 nt.assert_equal(d['a'], 'called')
398
399 def test_fixed():
400 c = interactive(f, a=widgets.fixed(5), b='text')
401 nt.assert_equal(len(c.children), 1)
402 w = c.children[0]
403 check_widget(w,
404 cls=widgets.TextWidget,
405 value='text',
406 description='b',
407 )
408
This diff has been collapsed as it changes many lines, (819 lines changed) Show them Hide them
@@ -0,0 +1,819 b''
1 """Function signature objects for callables
2
3 Back port of Python 3.3's function signature tools from the inspect module,
4 modified to be compatible with Python 2.6, 2.7 and 3.2+.
5 """
6
7 #-----------------------------------------------------------------------------
8 # Python 3.3 stdlib inspect.py is public domain
9 #
10 # Backports Copyright (C) 2013 Aaron Iles
11 # Used under Apache License Version 2.0
12 #
13 # Further Changes are Copyright (C) 2013 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 from __future__ import absolute_import, division, print_function
20 import itertools
21 import functools
22 import re
23 import types
24
25
26 # patch for single-file
27 # we don't support 2.6, so we can just import OrderedDict
28 from collections import OrderedDict
29
30 __version__ = '0.3'
31 # end patch
32
33 __all__ = ['BoundArguments', 'Parameter', 'Signature', 'signature']
34
35
36 _WrapperDescriptor = type(type.__call__)
37 _MethodWrapper = type(all.__call__)
38
39 _NonUserDefinedCallables = (_WrapperDescriptor,
40 _MethodWrapper,
41 types.BuiltinFunctionType)
42
43
44 def formatannotation(annotation, base_module=None):
45 if isinstance(annotation, type):
46 if annotation.__module__ in ('builtins', '__builtin__', base_module):
47 return annotation.__name__
48 return annotation.__module__+'.'+annotation.__name__
49 return repr(annotation)
50
51
52 def _get_user_defined_method(cls, method_name, *nested):
53 try:
54 if cls is type:
55 return
56 meth = getattr(cls, method_name)
57 for name in nested:
58 meth = getattr(meth, name, meth)
59 except AttributeError:
60 return
61 else:
62 if not isinstance(meth, _NonUserDefinedCallables):
63 # Once '__signature__' will be added to 'C'-level
64 # callables, this check won't be necessary
65 return meth
66
67
68 def signature(obj):
69 '''Get a signature object for the passed callable.'''
70
71 if not callable(obj):
72 raise TypeError('{0!r} is not a callable object'.format(obj))
73
74 if isinstance(obj, types.MethodType):
75 # In this case we skip the first parameter of the underlying
76 # function (usually `self` or `cls`).
77 sig = signature(obj.__func__)
78 return sig.replace(parameters=tuple(sig.parameters.values())[1:])
79
80 try:
81 sig = obj.__signature__
82 except AttributeError:
83 pass
84 else:
85 if sig is not None:
86 return sig
87
88 try:
89 # Was this function wrapped by a decorator?
90 wrapped = obj.__wrapped__
91 except AttributeError:
92 pass
93 else:
94 return signature(wrapped)
95
96 if isinstance(obj, types.FunctionType):
97 return Signature.from_function(obj)
98
99 if isinstance(obj, functools.partial):
100 sig = signature(obj.func)
101
102 new_params = OrderedDict(sig.parameters.items())
103
104 partial_args = obj.args or ()
105 partial_keywords = obj.keywords or {}
106 try:
107 ba = sig.bind_partial(*partial_args, **partial_keywords)
108 except TypeError as ex:
109 msg = 'partial object {0!r} has incorrect arguments'.format(obj)
110 raise ValueError(msg)
111
112 for arg_name, arg_value in ba.arguments.items():
113 param = new_params[arg_name]
114 if arg_name in partial_keywords:
115 # We set a new default value, because the following code
116 # is correct:
117 #
118 # >>> def foo(a): print(a)
119 # >>> print(partial(partial(foo, a=10), a=20)())
120 # 20
121 # >>> print(partial(partial(foo, a=10), a=20)(a=30))
122 # 30
123 #
124 # So, with 'partial' objects, passing a keyword argument is
125 # like setting a new default value for the corresponding
126 # parameter
127 #
128 # We also mark this parameter with '_partial_kwarg'
129 # flag. Later, in '_bind', the 'default' value of this
130 # parameter will be added to 'kwargs', to simulate
131 # the 'functools.partial' real call.
132 new_params[arg_name] = param.replace(default=arg_value,
133 _partial_kwarg=True)
134
135 elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and
136 not param._partial_kwarg):
137 new_params.pop(arg_name)
138
139 return sig.replace(parameters=new_params.values())
140
141 sig = None
142 if isinstance(obj, type):
143 # obj is a class or a metaclass
144
145 # First, let's see if it has an overloaded __call__ defined
146 # in its metaclass
147 call = _get_user_defined_method(type(obj), '__call__')
148 if call is not None:
149 sig = signature(call)
150 else:
151 # Now we check if the 'obj' class has a '__new__' method
152 new = _get_user_defined_method(obj, '__new__')
153 if new is not None:
154 sig = signature(new)
155 else:
156 # Finally, we should have at least __init__ implemented
157 init = _get_user_defined_method(obj, '__init__')
158 if init is not None:
159 sig = signature(init)
160 elif not isinstance(obj, _NonUserDefinedCallables):
161 # An object with __call__
162 # We also check that the 'obj' is not an instance of
163 # _WrapperDescriptor or _MethodWrapper to avoid
164 # infinite recursion (and even potential segfault)
165 call = _get_user_defined_method(type(obj), '__call__', 'im_func')
166 if call is not None:
167 sig = signature(call)
168
169 if sig is not None:
170 return sig
171
172 if isinstance(obj, types.BuiltinFunctionType):
173 # Raise a nicer error message for builtins
174 msg = 'no signature found for builtin function {0!r}'.format(obj)
175 raise ValueError(msg)
176
177 raise ValueError('callable {0!r} is not supported by signature'.format(obj))
178
179
180 class _void(object):
181 '''A private marker - used in Parameter & Signature'''
182
183
184 class _empty(object):
185 pass
186
187
188 class _ParameterKind(int):
189 def __new__(self, *args, **kwargs):
190 obj = int.__new__(self, *args)
191 obj._name = kwargs['name']
192 return obj
193
194 def __str__(self):
195 return self._name
196
197 def __repr__(self):
198 return '<_ParameterKind: {0!r}>'.format(self._name)
199
200
201 _POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY')
202 _POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD')
203 _VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL')
204 _KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY')
205 _VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD')
206
207
208 class Parameter(object):
209 '''Represents a parameter in a function signature.
210
211 Has the following public attributes:
212
213 * name : str
214 The name of the parameter as a string.
215 * default : object
216 The default value for the parameter if specified. If the
217 parameter has no default value, this attribute is not set.
218 * annotation
219 The annotation for the parameter if specified. If the
220 parameter has no annotation, this attribute is not set.
221 * kind : str
222 Describes how argument values are bound to the parameter.
223 Possible values: `Parameter.POSITIONAL_ONLY`,
224 `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
225 `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
226 '''
227
228 __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg')
229
230 POSITIONAL_ONLY = _POSITIONAL_ONLY
231 POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
232 VAR_POSITIONAL = _VAR_POSITIONAL
233 KEYWORD_ONLY = _KEYWORD_ONLY
234 VAR_KEYWORD = _VAR_KEYWORD
235
236 empty = _empty
237
238 def __init__(self, name, kind, default=_empty, annotation=_empty,
239 _partial_kwarg=False):
240
241 if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
242 _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
243 raise ValueError("invalid value for 'Parameter.kind' attribute")
244 self._kind = kind
245
246 if default is not _empty:
247 if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
248 msg = '{0} parameters cannot have default values'.format(kind)
249 raise ValueError(msg)
250 self._default = default
251 self._annotation = annotation
252
253 if name is None:
254 if kind != _POSITIONAL_ONLY:
255 raise ValueError("None is not a valid name for a "
256 "non-positional-only parameter")
257 self._name = name
258 else:
259 name = str(name)
260 if kind != _POSITIONAL_ONLY and not re.match(r'[a-z_]\w*$', name, re.I):
261 msg = '{0!r} is not a valid parameter name'.format(name)
262 raise ValueError(msg)
263 self._name = name
264
265 self._partial_kwarg = _partial_kwarg
266
267 @property
268 def name(self):
269 return self._name
270
271 @property
272 def default(self):
273 return self._default
274
275 @property
276 def annotation(self):
277 return self._annotation
278
279 @property
280 def kind(self):
281 return self._kind
282
283 def replace(self, name=_void, kind=_void, annotation=_void,
284 default=_void, _partial_kwarg=_void):
285 '''Creates a customized copy of the Parameter.'''
286
287 if name is _void:
288 name = self._name
289
290 if kind is _void:
291 kind = self._kind
292
293 if annotation is _void:
294 annotation = self._annotation
295
296 if default is _void:
297 default = self._default
298
299 if _partial_kwarg is _void:
300 _partial_kwarg = self._partial_kwarg
301
302 return type(self)(name, kind, default=default, annotation=annotation,
303 _partial_kwarg=_partial_kwarg)
304
305 def __str__(self):
306 kind = self.kind
307
308 formatted = self._name
309 if kind == _POSITIONAL_ONLY:
310 if formatted is None:
311 formatted = ''
312 formatted = '<{0}>'.format(formatted)
313
314 # Add annotation and default value
315 if self._annotation is not _empty:
316 formatted = '{0}:{1}'.format(formatted,
317 formatannotation(self._annotation))
318
319 if self._default is not _empty:
320 formatted = '{0}={1}'.format(formatted, repr(self._default))
321
322 if kind == _VAR_POSITIONAL:
323 formatted = '*' + formatted
324 elif kind == _VAR_KEYWORD:
325 formatted = '**' + formatted
326
327 return formatted
328
329 def __repr__(self):
330 return '<{0} at {1:#x} {2!r}>'.format(self.__class__.__name__,
331 id(self), self.name)
332
333 def __hash__(self):
334 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
335 raise TypeError(msg)
336
337 def __eq__(self, other):
338 return (issubclass(other.__class__, Parameter) and
339 self._name == other._name and
340 self._kind == other._kind and
341 self._default == other._default and
342 self._annotation == other._annotation)
343
344 def __ne__(self, other):
345 return not self.__eq__(other)
346
347
348 class BoundArguments(object):
349 '''Result of `Signature.bind` call. Holds the mapping of arguments
350 to the function's parameters.
351
352 Has the following public attributes:
353
354 * arguments : OrderedDict
355 An ordered mutable mapping of parameters' names to arguments' values.
356 Does not contain arguments' default values.
357 * signature : Signature
358 The Signature object that created this instance.
359 * args : tuple
360 Tuple of positional arguments values.
361 * kwargs : dict
362 Dict of keyword arguments values.
363 '''
364
365 def __init__(self, signature, arguments):
366 self.arguments = arguments
367 self._signature = signature
368
369 @property
370 def signature(self):
371 return self._signature
372
373 @property
374 def args(self):
375 args = []
376 for param_name, param in self._signature.parameters.items():
377 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
378 param._partial_kwarg):
379 # Keyword arguments mapped by 'functools.partial'
380 # (Parameter._partial_kwarg is True) are mapped
381 # in 'BoundArguments.kwargs', along with VAR_KEYWORD &
382 # KEYWORD_ONLY
383 break
384
385 try:
386 arg = self.arguments[param_name]
387 except KeyError:
388 # We're done here. Other arguments
389 # will be mapped in 'BoundArguments.kwargs'
390 break
391 else:
392 if param.kind == _VAR_POSITIONAL:
393 # *args
394 args.extend(arg)
395 else:
396 # plain argument
397 args.append(arg)
398
399 return tuple(args)
400
401 @property
402 def kwargs(self):
403 kwargs = {}
404 kwargs_started = False
405 for param_name, param in self._signature.parameters.items():
406 if not kwargs_started:
407 if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or
408 param._partial_kwarg):
409 kwargs_started = True
410 else:
411 if param_name not in self.arguments:
412 kwargs_started = True
413 continue
414
415 if not kwargs_started:
416 continue
417
418 try:
419 arg = self.arguments[param_name]
420 except KeyError:
421 pass
422 else:
423 if param.kind == _VAR_KEYWORD:
424 # **kwargs
425 kwargs.update(arg)
426 else:
427 # plain keyword argument
428 kwargs[param_name] = arg
429
430 return kwargs
431
432 def __hash__(self):
433 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
434 raise TypeError(msg)
435
436 def __eq__(self, other):
437 return (issubclass(other.__class__, BoundArguments) and
438 self.signature == other.signature and
439 self.arguments == other.arguments)
440
441 def __ne__(self, other):
442 return not self.__eq__(other)
443
444
445 class Signature(object):
446 '''A Signature object represents the overall signature of a function.
447 It stores a Parameter object for each parameter accepted by the
448 function, as well as information specific to the function itself.
449
450 A Signature object has the following public attributes and methods:
451
452 * parameters : OrderedDict
453 An ordered mapping of parameters' names to the corresponding
454 Parameter objects (keyword-only arguments are in the same order
455 as listed in `code.co_varnames`).
456 * return_annotation : object
457 The annotation for the return type of the function if specified.
458 If the function has no annotation for its return type, this
459 attribute is not set.
460 * bind(*args, **kwargs) -> BoundArguments
461 Creates a mapping from positional and keyword arguments to
462 parameters.
463 * bind_partial(*args, **kwargs) -> BoundArguments
464 Creates a partial mapping from positional and keyword arguments
465 to parameters (simulating 'functools.partial' behavior.)
466 '''
467
468 __slots__ = ('_return_annotation', '_parameters')
469
470 _parameter_cls = Parameter
471 _bound_arguments_cls = BoundArguments
472
473 empty = _empty
474
475 def __init__(self, parameters=None, return_annotation=_empty,
476 __validate_parameters__=True):
477 '''Constructs Signature from the given list of Parameter
478 objects and 'return_annotation'. All arguments are optional.
479 '''
480
481 if parameters is None:
482 params = OrderedDict()
483 else:
484 if __validate_parameters__:
485 params = OrderedDict()
486 top_kind = _POSITIONAL_ONLY
487
488 for idx, param in enumerate(parameters):
489 kind = param.kind
490 if kind < top_kind:
491 msg = 'wrong parameter order: {0} before {1}'
492 msg = msg.format(top_kind, param.kind)
493 raise ValueError(msg)
494 else:
495 top_kind = kind
496
497 name = param.name
498 if name is None:
499 name = str(idx)
500 param = param.replace(name=name)
501
502 if name in params:
503 msg = 'duplicate parameter name: {0!r}'.format(name)
504 raise ValueError(msg)
505 params[name] = param
506 else:
507 params = OrderedDict(((param.name, param)
508 for param in parameters))
509
510 self._parameters = params
511 self._return_annotation = return_annotation
512
513 @classmethod
514 def from_function(cls, func):
515 '''Constructs Signature for the given python function'''
516
517 if not isinstance(func, types.FunctionType):
518 raise TypeError('{0!r} is not a Python function'.format(func))
519
520 Parameter = cls._parameter_cls
521
522 # Parameter information.
523 func_code = func.__code__
524 pos_count = func_code.co_argcount
525 arg_names = func_code.co_varnames
526 positional = tuple(arg_names[:pos_count])
527 keyword_only_count = getattr(func_code, 'co_kwonlyargcount', 0)
528 keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
529 annotations = getattr(func, '__annotations__', {})
530 defaults = func.__defaults__
531 kwdefaults = getattr(func, '__kwdefaults__', None)
532
533 if defaults:
534 pos_default_count = len(defaults)
535 else:
536 pos_default_count = 0
537
538 parameters = []
539
540 # Non-keyword-only parameters w/o defaults.
541 non_default_count = pos_count - pos_default_count
542 for name in positional[:non_default_count]:
543 annotation = annotations.get(name, _empty)
544 parameters.append(Parameter(name, annotation=annotation,
545 kind=_POSITIONAL_OR_KEYWORD))
546
547 # ... w/ defaults.
548 for offset, name in enumerate(positional[non_default_count:]):
549 annotation = annotations.get(name, _empty)
550 parameters.append(Parameter(name, annotation=annotation,
551 kind=_POSITIONAL_OR_KEYWORD,
552 default=defaults[offset]))
553
554 # *args
555 if func_code.co_flags & 0x04:
556 name = arg_names[pos_count + keyword_only_count]
557 annotation = annotations.get(name, _empty)
558 parameters.append(Parameter(name, annotation=annotation,
559 kind=_VAR_POSITIONAL))
560
561 # Keyword-only parameters.
562 for name in keyword_only:
563 default = _empty
564 if kwdefaults is not None:
565 default = kwdefaults.get(name, _empty)
566
567 annotation = annotations.get(name, _empty)
568 parameters.append(Parameter(name, annotation=annotation,
569 kind=_KEYWORD_ONLY,
570 default=default))
571 # **kwargs
572 if func_code.co_flags & 0x08:
573 index = pos_count + keyword_only_count
574 if func_code.co_flags & 0x04:
575 index += 1
576
577 name = arg_names[index]
578 annotation = annotations.get(name, _empty)
579 parameters.append(Parameter(name, annotation=annotation,
580 kind=_VAR_KEYWORD))
581
582 return cls(parameters,
583 return_annotation=annotations.get('return', _empty),
584 __validate_parameters__=False)
585
586 @property
587 def parameters(self):
588 try:
589 return types.MappingProxyType(self._parameters)
590 except AttributeError:
591 return OrderedDict(self._parameters.items())
592
593 @property
594 def return_annotation(self):
595 return self._return_annotation
596
597 def replace(self, parameters=_void, return_annotation=_void):
598 '''Creates a customized copy of the Signature.
599 Pass 'parameters' and/or 'return_annotation' arguments
600 to override them in the new copy.
601 '''
602
603 if parameters is _void:
604 parameters = self.parameters.values()
605
606 if return_annotation is _void:
607 return_annotation = self._return_annotation
608
609 return type(self)(parameters,
610 return_annotation=return_annotation)
611
612 def __hash__(self):
613 msg = "unhashable type: '{0}'".format(self.__class__.__name__)
614 raise TypeError(msg)
615
616 def __eq__(self, other):
617 if (not issubclass(type(other), Signature) or
618 self.return_annotation != other.return_annotation or
619 len(self.parameters) != len(other.parameters)):
620 return False
621
622 other_positions = dict((param, idx)
623 for idx, param in enumerate(other.parameters.keys()))
624
625 for idx, (param_name, param) in enumerate(self.parameters.items()):
626 if param.kind == _KEYWORD_ONLY:
627 try:
628 other_param = other.parameters[param_name]
629 except KeyError:
630 return False
631 else:
632 if param != other_param:
633 return False
634 else:
635 try:
636 other_idx = other_positions[param_name]
637 except KeyError:
638 return False
639 else:
640 if (idx != other_idx or
641 param != other.parameters[param_name]):
642 return False
643
644 return True
645
646 def __ne__(self, other):
647 return not self.__eq__(other)
648
649 def _bind(self, args, kwargs, partial=False):
650 '''Private method. Don't use directly.'''
651
652 arguments = OrderedDict()
653
654 parameters = iter(self.parameters.values())
655 parameters_ex = ()
656 arg_vals = iter(args)
657
658 if partial:
659 # Support for binding arguments to 'functools.partial' objects.
660 # See 'functools.partial' case in 'signature()' implementation
661 # for details.
662 for param_name, param in self.parameters.items():
663 if (param._partial_kwarg and param_name not in kwargs):
664 # Simulating 'functools.partial' behavior
665 kwargs[param_name] = param.default
666
667 while True:
668 # Let's iterate through the positional arguments and corresponding
669 # parameters
670 try:
671 arg_val = next(arg_vals)
672 except StopIteration:
673 # No more positional arguments
674 try:
675 param = next(parameters)
676 except StopIteration:
677 # No more parameters. That's it. Just need to check that
678 # we have no `kwargs` after this while loop
679 break
680 else:
681 if param.kind == _VAR_POSITIONAL:
682 # That's OK, just empty *args. Let's start parsing
683 # kwargs
684 break
685 elif param.name in kwargs:
686 if param.kind == _POSITIONAL_ONLY:
687 msg = '{arg!r} parameter is positional only, ' \
688 'but was passed as a keyword'
689 msg = msg.format(arg=param.name)
690 raise TypeError(msg)
691 parameters_ex = (param,)
692 break
693 elif (param.kind == _VAR_KEYWORD or
694 param.default is not _empty):
695 # That's fine too - we have a default value for this
696 # parameter. So, lets start parsing `kwargs`, starting
697 # with the current parameter
698 parameters_ex = (param,)
699 break
700 else:
701 if partial:
702 parameters_ex = (param,)
703 break
704 else:
705 msg = '{arg!r} parameter lacking default value'
706 msg = msg.format(arg=param.name)
707 raise TypeError(msg)
708 else:
709 # We have a positional argument to process
710 try:
711 param = next(parameters)
712 except StopIteration:
713 raise TypeError('too many positional arguments')
714 else:
715 if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
716 # Looks like we have no parameter for this positional
717 # argument
718 raise TypeError('too many positional arguments')
719
720 if param.kind == _VAR_POSITIONAL:
721 # We have an '*args'-like argument, let's fill it with
722 # all positional arguments we have left and move on to
723 # the next phase
724 values = [arg_val]
725 values.extend(arg_vals)
726 arguments[param.name] = tuple(values)
727 break
728
729 if param.name in kwargs:
730 raise TypeError('multiple values for argument '
731 '{arg!r}'.format(arg=param.name))
732
733 arguments[param.name] = arg_val
734
735 # Now, we iterate through the remaining parameters to process
736 # keyword arguments
737 kwargs_param = None
738 for param in itertools.chain(parameters_ex, parameters):
739 if param.kind == _POSITIONAL_ONLY:
740 # This should never happen in case of a properly built
741 # Signature object (but let's have this check here
742 # to ensure correct behaviour just in case)
743 raise TypeError('{arg!r} parameter is positional only, '
744 'but was passed as a keyword'. \
745 format(arg=param.name))
746
747 if param.kind == _VAR_KEYWORD:
748 # Memorize that we have a '**kwargs'-like parameter
749 kwargs_param = param
750 continue
751
752 param_name = param.name
753 try:
754 arg_val = kwargs.pop(param_name)
755 except KeyError:
756 # We have no value for this parameter. It's fine though,
757 # if it has a default value, or it is an '*args'-like
758 # parameter, left alone by the processing of positional
759 # arguments.
760 if (not partial and param.kind != _VAR_POSITIONAL and
761 param.default is _empty):
762 raise TypeError('{arg!r} parameter lacking default value'. \
763 format(arg=param_name))
764
765 else:
766 arguments[param_name] = arg_val
767
768 if kwargs:
769 if kwargs_param is not None:
770 # Process our '**kwargs'-like parameter
771 arguments[kwargs_param.name] = kwargs
772 else:
773 raise TypeError('too many keyword arguments')
774
775 return self._bound_arguments_cls(self, arguments)
776
777 def bind(self, *args, **kwargs):
778 '''Get a BoundArguments object, that maps the passed `args`
779 and `kwargs` to the function's signature. Raises `TypeError`
780 if the passed arguments can not be bound.
781 '''
782 return self._bind(args, kwargs)
783
784 def bind_partial(self, *args, **kwargs):
785 '''Get a BoundArguments object, that partially maps the
786 passed `args` and `kwargs` to the function's signature.
787 Raises `TypeError` if the passed arguments can not be bound.
788 '''
789 return self._bind(args, kwargs, partial=True)
790
791 def __str__(self):
792 result = []
793 render_kw_only_separator = True
794 for idx, param in enumerate(self.parameters.values()):
795 formatted = str(param)
796
797 kind = param.kind
798 if kind == _VAR_POSITIONAL:
799 # OK, we have an '*args'-like parameter, so we won't need
800 # a '*' to separate keyword-only arguments
801 render_kw_only_separator = False
802 elif kind == _KEYWORD_ONLY and render_kw_only_separator:
803 # We have a keyword-only parameter to render and we haven't
804 # rendered an '*args'-like parameter before, so add a '*'
805 # separator to the parameters list ("foo(arg1, *, arg2)" case)
806 result.append('*')
807 # This condition should be only triggered once, so
808 # reset the flag
809 render_kw_only_separator = False
810
811 result.append(formatted)
812
813 rendered = '({0})'.format(', '.join(result))
814
815 if self.return_annotation is not _empty:
816 anno = formatannotation(self.return_annotation)
817 rendered += ' -> {0}'.format(anno)
818
819 return rendered
1 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
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,121 +1,149 b''
1 1
2 2 /* Flexible box model classes */
3 3 /* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
4 4
5 5 .hbox {
6 6 display: -webkit-box;
7 7 -webkit-box-orient: horizontal;
8 8 -webkit-box-align: stretch;
9 9
10 10 display: -moz-box;
11 11 -moz-box-orient: horizontal;
12 12 -moz-box-align: stretch;
13 13
14 14 display: box;
15 15 box-orient: horizontal;
16 16 box-align: stretch;
17
18 display: flex;
19 flex-direction: row;
20 align-items: stretch;
17 21 }
18 22
19 23 .hbox > * {
20 24 -webkit-box-flex: 0;
21 25 -moz-box-flex: 0;
22 26 box-flex: 0;
27 flex: auto;
23 28 }
24 29
25 30 .vbox {
26 31 display: -webkit-box;
27 32 -webkit-box-orient: vertical;
28 33 -webkit-box-align: stretch;
29 34
30 35 display: -moz-box;
31 36 -moz-box-orient: vertical;
32 37 -moz-box-align: stretch;
33 38
34 39 display: box;
35 40 box-orient: vertical;
36 41 box-align: stretch;
37 42 /* width must be 100% to force FF to behave like webkit */
38 43 width: 100%;
44
45 display: flex;
46 flex-direction: column;
47 align-items: stretch;
39 48 }
40 49
41 50 .vbox > * {
42 51 -webkit-box-flex: 0;
43 52 -moz-box-flex: 0;
44 53 box-flex: 0;
54 flex: auto;
45 55 }
46 56
47 57 .reverse {
48 58 -webkit-box-direction: reverse;
49 59 -moz-box-direction: reverse;
50 60 box-direction: reverse;
61 flex-direction: column-reverse;
51 62 }
52 63
53 64 .box-flex0 {
54 65 -webkit-box-flex: 0;
55 66 -moz-box-flex: 0;
56 67 box-flex: 0;
68 flex: auto;
57 69 }
58 70
59 71 .box-flex1 {
60 72 -webkit-box-flex: 1;
61 73 -moz-box-flex: 1;
62 74 box-flex: 1;
75 flex: 1;
63 76 }
64 77
65 78 .box-flex {
66 79 .box-flex1();
67 80 }
68 81
69 82 .box-flex2 {
70 83 -webkit-box-flex: 2;
71 84 -moz-box-flex: 2;
72 85 box-flex: 2;
86 flex: 2;
73 87 }
74 88
75 89 .box-group1 {
90 /*
91 Deprecated
92 Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/
93 */
76 94 -webkit-box-flex-group: 1;
77 95 -moz-box-flex-group: 1;
78 96 box-flex-group: 1;
79 97 }
80 98
81 99 .box-group2 {
100 /*
101 Deprecated
102 Grouping isn't supported in http://dev.w3.org/csswg/css-flexbox/
103 */
82 104 -webkit-box-flex-group: 2;
83 105 -moz-box-flex-group: 2;
84 106 box-flex-group: 2;
85 107 }
86 108
87 109 .start {
88 110 -webkit-box-pack: start;
89 111 -moz-box-pack: start;
90 112 box-pack: start;
113 justify-content: flex-start;
91 114 }
92 115
93 116 .end {
94 117 -webkit-box-pack: end;
95 118 -moz-box-pack: end;
96 119 box-pack: end;
120 justify-content: flex-end;
97 121 }
98 122
99 123 .center {
100 124 -webkit-box-pack: center;
101 125 -moz-box-pack: center;
102 126 box-pack: center;
127 justify-content: center;
103 128 }
104 129
105 130 .align-start {
106 131 -webkit-box-align: start;
107 132 -moz-box-align: start;
108 133 box-align: start;
134 align-content: flex-start;
109 135 }
110 136
111 137 .align-end {
112 138 -webkit-box-align: end;
113 139 -moz-box-align: end;
114 140 box-align: end;
141 align-content: flex-end;
115 142 }
116 143
117 144 .align-center {
118 145 -webkit-box-align: center;
119 146 -moz-box-align: center;
120 147 box-align: center;
148 align-content: center;
121 149 }
@@ -1,759 +1,764 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Keyboard management
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13 "use strict";
14 14
15 15 // Setup global keycodes and inverse keycodes.
16 16
17 17 // See http://unixpapa.com/js/key.html for a complete description. The short of
18 18 // it is that there are different keycode sets. Firefox uses the "Mozilla keycodes"
19 19 // and Webkit/IE use the "IE keycodes". These keycode sets are mostly the same
20 20 // but have minor differences.
21 21
22 22 // These apply to Firefox, (Webkit and IE)
23 23 var _keycodes = {
24 24 'a': 65, 'b': 66, 'c': 67, 'd': 68, 'e': 69, 'f': 70, 'g': 71, 'h': 72, 'i': 73,
25 25 'j': 74, 'k': 75, 'l': 76, 'm': 77, 'n': 78, 'o': 79, 'p': 80, 'q': 81, 'r': 82,
26 26 's': 83, 't': 84, 'u': 85, 'v': 86, 'w': 87, 'x': 88, 'y': 89, 'z': 90,
27 27 '1 !': 49, '2 @': 50, '3 #': 51, '4 $': 52, '5 %': 53, '6 ^': 54,
28 28 '7 &': 55, '8 *': 56, '9 (': 57, '0 )': 48,
29 29 '[ {': 219, '] }': 221, '` ~': 192, ', <': 188, '. >': 190, '/ ?': 191,
30 30 '\\ |': 220, '\' "': 222,
31 31 'numpad0': 96, 'numpad1': 97, 'numpad2': 98, 'numpad3': 99, 'numpad4': 100,
32 32 'numpad5': 101, 'numpad6': 102, 'numpad7': 103, 'numpad8': 104, 'numpad9': 105,
33 33 'multiply': 106, 'add': 107, 'subtract': 109, 'decimal': 110, 'divide': 111,
34 34 'f1': 112, 'f2': 113, 'f3': 114, 'f4': 115, 'f5': 116, 'f6': 117, 'f7': 118,
35 35 'f8': 119, 'f9': 120, 'f11': 122, 'f12': 123, 'f13': 124, 'f14': 125, 'f15': 126,
36 36 'backspace': 8, 'tab': 9, 'enter': 13, 'shift': 16, 'ctrl': 17, 'alt': 18,
37 37 'meta': 91, 'capslock': 20, 'esc': 27, 'space': 32, 'pageup': 33, 'pagedown': 34,
38 38 'end': 35, 'home': 36, 'left': 37, 'up': 38, 'right': 39, 'down': 40,
39 39 'insert': 45, 'delete': 46, 'numlock': 144,
40 40 };
41 41
42 42 // These apply to Firefox and Opera
43 43 var _mozilla_keycodes = {
44 44 '; :': 59, '= +': 61, '- _': 173, 'meta': 224
45 45 }
46 46
47 47 // This apply to Webkit and IE
48 48 var _ie_keycodes = {
49 49 '; :': 186, '= +': 187, '- _': 189,
50 50 }
51 51
52 52 var browser = IPython.utils.browser[0];
53 53 var platform = IPython.utils.platform;
54 54
55 55 if (browser === 'Firefox' || browser === 'Opera') {
56 56 $.extend(_keycodes, _mozilla_keycodes);
57 57 } else if (browser === 'Safari' || browser === 'Chrome' || browser === 'MSIE') {
58 58 $.extend(_keycodes, _ie_keycodes);
59 59 }
60 60
61 61 var keycodes = {};
62 62 var inv_keycodes = {};
63 63 for (var name in _keycodes) {
64 64 var names = name.split(' ');
65 65 if (names.length === 1) {
66 66 var n = names[0]
67 67 keycodes[n] = _keycodes[n]
68 68 inv_keycodes[_keycodes[n]] = n
69 69 } else {
70 70 var primary = names[0];
71 71 var secondary = names[1];
72 72 keycodes[primary] = _keycodes[name]
73 73 keycodes[secondary] = _keycodes[name]
74 74 inv_keycodes[_keycodes[name]] = primary
75 75 }
76 76 }
77 77
78 78
79 79 // Default keyboard shortcuts
80 80
81 81 var default_common_shortcuts = {
82 82 'shift' : {
83 83 help : '',
84 84 help_index : '',
85 85 handler : function (event) {
86 86 // ignore shift keydown
87 87 return true;
88 88 }
89 89 },
90 90 'shift+enter' : {
91 91 help : 'run cell, select below',
92 92 help_index : 'ba',
93 93 handler : function (event) {
94 94 IPython.notebook.execute_cell_and_select_below();
95 95 return false;
96 96 }
97 97 },
98 98 'ctrl+enter' : {
99 99 help : 'run cell',
100 100 help_index : 'bb',
101 101 handler : function (event) {
102 102 IPython.notebook.execute_cell();
103 103 return false;
104 104 }
105 105 },
106 106 'alt+enter' : {
107 107 help : 'run cell, insert below',
108 108 help_index : 'bc',
109 109 handler : function (event) {
110 110 IPython.notebook.execute_cell_and_insert_below();
111 111 return false;
112 112 }
113 113 }
114 114 }
115 115
116 116 if (platform === 'MacOS') {
117 117 default_common_shortcuts['cmd+s'] =
118 118 {
119 119 help : 'save notebook',
120 120 help_index : 'fb',
121 121 handler : function (event) {
122 122 IPython.notebook.save_checkpoint();
123 123 event.preventDefault();
124 124 return false;
125 125 }
126 126 };
127 127 } else {
128 128 default_common_shortcuts['ctrl+s'] =
129 129 {
130 130 help : 'save notebook',
131 131 help_index : 'fb',
132 132 handler : function (event) {
133 133 IPython.notebook.save_checkpoint();
134 134 event.preventDefault();
135 135 return false;
136 136 }
137 137 };
138 138 }
139 139
140 140 // Edit mode defaults
141 141
142 142 var default_edit_shortcuts = {
143 143 'esc' : {
144 144 help : 'command mode',
145 145 help_index : 'aa',
146 146 handler : function (event) {
147 147 IPython.notebook.command_mode();
148 148 IPython.notebook.focus_cell();
149 149 return false;
150 150 }
151 151 },
152 152 'ctrl+m' : {
153 153 help : 'command mode',
154 154 help_index : 'ab',
155 155 handler : function (event) {
156 156 IPython.notebook.command_mode();
157 157 IPython.notebook.focus_cell();
158 158 return false;
159 159 }
160 160 },
161 161 'up' : {
162 162 help : '',
163 163 help_index : '',
164 164 handler : function (event) {
165 165 var cell = IPython.notebook.get_selected_cell();
166 166 if (cell && cell.at_top()) {
167 167 event.preventDefault();
168 168 IPython.notebook.command_mode()
169 169 IPython.notebook.select_prev();
170 170 IPython.notebook.edit_mode();
171 171 return false;
172 172 };
173 173 }
174 174 },
175 175 'down' : {
176 176 help : '',
177 177 help_index : '',
178 178 handler : function (event) {
179 179 var cell = IPython.notebook.get_selected_cell();
180 180 if (cell && cell.at_bottom()) {
181 181 event.preventDefault();
182 182 IPython.notebook.command_mode()
183 183 IPython.notebook.select_next();
184 184 IPython.notebook.edit_mode();
185 185 return false;
186 186 };
187 187 }
188 188 },
189 189 'alt+-' : {
190 190 help : 'split cell',
191 191 help_index : 'ea',
192 192 handler : function (event) {
193 193 IPython.notebook.split_cell();
194 194 return false;
195 195 }
196 196 },
197 197 'alt+subtract' : {
198 198 help : '',
199 199 help_index : 'eb',
200 200 handler : function (event) {
201 201 IPython.notebook.split_cell();
202 202 return false;
203 203 }
204 204 },
205 205 'tab' : {
206 206 help : 'indent or complete',
207 207 help_index : 'ec',
208 208 },
209 209 'shift+tab' : {
210 210 help : 'tooltip',
211 211 help_index : 'ed',
212 212 },
213 213 }
214 214
215 215 if (platform === 'MacOS') {
216 216 default_edit_shortcuts['cmd+/'] =
217 217 {
218 218 help : 'toggle comment',
219 219 help_index : 'ee'
220 220 };
221 221 default_edit_shortcuts['cmd+]'] =
222 222 {
223 223 help : 'indent',
224 224 help_index : 'ef'
225 225 };
226 226 default_edit_shortcuts['cmd+['] =
227 227 {
228 228 help : 'dedent',
229 229 help_index : 'eg'
230 230 };
231 231 } else {
232 232 default_edit_shortcuts['ctrl+/'] =
233 233 {
234 234 help : 'toggle comment',
235 235 help_index : 'ee'
236 236 };
237 237 default_edit_shortcuts['ctrl+]'] =
238 238 {
239 239 help : 'indent',
240 240 help_index : 'ef'
241 241 };
242 242 default_edit_shortcuts['ctrl+['] =
243 243 {
244 244 help : 'dedent',
245 245 help_index : 'eg'
246 246 };
247 247 }
248 248
249 249 // Command mode defaults
250 250
251 251 var default_command_shortcuts = {
252 252 'enter' : {
253 253 help : 'edit mode',
254 254 help_index : 'aa',
255 255 handler : function (event) {
256 256 IPython.notebook.edit_mode();
257 257 return false;
258 258 }
259 259 },
260 260 'up' : {
261 261 help : 'select previous cell',
262 262 help_index : 'da',
263 263 handler : function (event) {
264 264 var index = IPython.notebook.get_selected_index();
265 265 if (index !== 0 && index !== null) {
266 266 IPython.notebook.select_prev();
267 267 var cell = IPython.notebook.get_selected_cell();
268 268 cell.focus_cell();
269 269 };
270 270 return false;
271 271 }
272 272 },
273 273 'down' : {
274 274 help : 'select next cell',
275 275 help_index : 'db',
276 276 handler : function (event) {
277 277 var index = IPython.notebook.get_selected_index();
278 278 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
279 279 IPython.notebook.select_next();
280 280 var cell = IPython.notebook.get_selected_cell();
281 281 cell.focus_cell();
282 282 };
283 283 return false;
284 284 }
285 285 },
286 286 'k' : {
287 287 help : 'select previous cell',
288 288 help_index : 'dc',
289 289 handler : function (event) {
290 290 var index = IPython.notebook.get_selected_index();
291 291 if (index !== 0 && index !== null) {
292 292 IPython.notebook.select_prev();
293 293 var cell = IPython.notebook.get_selected_cell();
294 294 cell.focus_cell();
295 295 };
296 296 return false;
297 297 }
298 298 },
299 299 'j' : {
300 300 help : 'select next cell',
301 301 help_index : 'dd',
302 302 handler : function (event) {
303 303 var index = IPython.notebook.get_selected_index();
304 304 if (index !== (IPython.notebook.ncells()-1) && index !== null) {
305 305 IPython.notebook.select_next();
306 306 var cell = IPython.notebook.get_selected_cell();
307 307 cell.focus_cell();
308 308 };
309 309 return false;
310 310 }
311 311 },
312 312 'x' : {
313 313 help : 'cut cell',
314 314 help_index : 'ee',
315 315 handler : function (event) {
316 316 IPython.notebook.cut_cell();
317 317 return false;
318 318 }
319 319 },
320 320 'c' : {
321 321 help : 'copy cell',
322 322 help_index : 'ef',
323 323 handler : function (event) {
324 324 IPython.notebook.copy_cell();
325 325 return false;
326 326 }
327 327 },
328 328 'shift+v' : {
329 329 help : 'paste cell above',
330 330 help_index : 'eg',
331 331 handler : function (event) {
332 332 IPython.notebook.paste_cell_above();
333 333 return false;
334 334 }
335 335 },
336 336 'v' : {
337 337 help : 'paste cell below',
338 338 help_index : 'eh',
339 339 handler : function (event) {
340 340 IPython.notebook.paste_cell_below();
341 341 return false;
342 342 }
343 343 },
344 344 'd' : {
345 345 help : 'delete cell (press twice)',
346 346 help_index : 'ej',
347 347 count: 2,
348 348 handler : function (event) {
349 349 IPython.notebook.delete_cell();
350 350 return false;
351 351 }
352 352 },
353 353 'a' : {
354 354 help : 'insert cell above',
355 355 help_index : 'ec',
356 356 handler : function (event) {
357 357 IPython.notebook.insert_cell_above('code');
358 358 IPython.notebook.select_prev();
359 359 IPython.notebook.focus_cell();
360 360 return false;
361 361 }
362 362 },
363 363 'b' : {
364 364 help : 'insert cell below',
365 365 help_index : 'ed',
366 366 handler : function (event) {
367 367 IPython.notebook.insert_cell_below('code');
368 368 IPython.notebook.select_next();
369 369 IPython.notebook.focus_cell();
370 370 return false;
371 371 }
372 372 },
373 373 'y' : {
374 374 help : 'to code',
375 375 help_index : 'ca',
376 376 handler : function (event) {
377 377 IPython.notebook.to_code();
378 378 return false;
379 379 }
380 380 },
381 381 'm' : {
382 382 help : 'to markdown',
383 383 help_index : 'cb',
384 384 handler : function (event) {
385 385 IPython.notebook.to_markdown();
386 386 return false;
387 387 }
388 388 },
389 389 'r' : {
390 390 help : 'to raw',
391 391 help_index : 'cc',
392 392 handler : function (event) {
393 393 IPython.notebook.to_raw();
394 394 return false;
395 395 }
396 396 },
397 397 '1' : {
398 398 help : 'to heading 1',
399 399 help_index : 'cd',
400 400 handler : function (event) {
401 401 IPython.notebook.to_heading(undefined, 1);
402 402 return false;
403 403 }
404 404 },
405 405 '2' : {
406 406 help : 'to heading 2',
407 407 help_index : 'ce',
408 408 handler : function (event) {
409 409 IPython.notebook.to_heading(undefined, 2);
410 410 return false;
411 411 }
412 412 },
413 413 '3' : {
414 414 help : 'to heading 3',
415 415 help_index : 'cf',
416 416 handler : function (event) {
417 417 IPython.notebook.to_heading(undefined, 3);
418 418 return false;
419 419 }
420 420 },
421 421 '4' : {
422 422 help : 'to heading 4',
423 423 help_index : 'cg',
424 424 handler : function (event) {
425 425 IPython.notebook.to_heading(undefined, 4);
426 426 return false;
427 427 }
428 428 },
429 429 '5' : {
430 430 help : 'to heading 5',
431 431 help_index : 'ch',
432 432 handler : function (event) {
433 433 IPython.notebook.to_heading(undefined, 5);
434 434 return false;
435 435 }
436 436 },
437 437 '6' : {
438 438 help : 'to heading 6',
439 439 help_index : 'ci',
440 440 handler : function (event) {
441 441 IPython.notebook.to_heading(undefined, 6);
442 442 return false;
443 443 }
444 444 },
445 445 'o' : {
446 446 help : 'toggle output',
447 447 help_index : 'gb',
448 448 handler : function (event) {
449 449 IPython.notebook.toggle_output();
450 450 return false;
451 451 }
452 452 },
453 453 'shift+o' : {
454 454 help : 'toggle output scrolling',
455 455 help_index : 'gc',
456 456 handler : function (event) {
457 457 IPython.notebook.toggle_output_scroll();
458 458 return false;
459 459 }
460 460 },
461 461 's' : {
462 462 help : 'save notebook',
463 463 help_index : 'fa',
464 464 handler : function (event) {
465 465 IPython.notebook.save_checkpoint();
466 466 return false;
467 467 }
468 468 },
469 469 'ctrl+j' : {
470 470 help : 'move cell down',
471 471 help_index : 'eb',
472 472 handler : function (event) {
473 473 IPython.notebook.move_cell_down();
474 474 return false;
475 475 }
476 476 },
477 477 'ctrl+k' : {
478 478 help : 'move cell up',
479 479 help_index : 'ea',
480 480 handler : function (event) {
481 481 IPython.notebook.move_cell_up();
482 482 return false;
483 483 }
484 484 },
485 485 'l' : {
486 486 help : 'toggle line numbers',
487 487 help_index : 'ga',
488 488 handler : function (event) {
489 489 IPython.notebook.cell_toggle_line_numbers();
490 490 return false;
491 491 }
492 492 },
493 493 'i' : {
494 494 help : 'interrupt kernel (press twice)',
495 495 help_index : 'ha',
496 496 count: 2,
497 497 handler : function (event) {
498 498 IPython.notebook.kernel.interrupt();
499 499 return false;
500 500 }
501 501 },
502 502 '0' : {
503 503 help : 'restart kernel (press twice)',
504 504 help_index : 'hb',
505 505 count: 2,
506 506 handler : function (event) {
507 507 IPython.notebook.restart_kernel();
508 508 return false;
509 509 }
510 510 },
511 511 'h' : {
512 512 help : 'keyboard shortcuts',
513 513 help_index : 'gd',
514 514 handler : function (event) {
515 515 IPython.quick_help.show_keyboard_shortcuts();
516 516 return false;
517 517 }
518 518 },
519 519 'z' : {
520 520 help : 'undo last delete',
521 521 help_index : 'ei',
522 522 handler : function (event) {
523 523 IPython.notebook.undelete_cell();
524 524 return false;
525 525 }
526 526 },
527 527 'shift+m' : {
528 528 help : 'merge cell below',
529 529 help_index : 'ek',
530 530 handler : function (event) {
531 531 IPython.notebook.merge_cell_below();
532 532 return false;
533 533 }
534 534 },
535 535 }
536 536
537 537
538 538 // Shortcut manager class
539 539
540 540 var ShortcutManager = function (delay) {
541 541 this._shortcuts = {}
542 542 this._counts = {}
543 this._timers = {}
543 544 this.delay = delay || 800; // delay in milliseconds
544 545 }
545 546
546 547 ShortcutManager.prototype.help = function () {
547 548 var help = [];
548 549 for (var shortcut in this._shortcuts) {
549 550 var help_string = this._shortcuts[shortcut]['help'];
550 551 var help_index = this._shortcuts[shortcut]['help_index'];
551 552 if (help_string) {
552 553 if (platform === 'MacOS') {
553 554 shortcut = shortcut.replace('meta', 'cmd');
554 555 }
555 556 help.push({
556 557 shortcut: shortcut,
557 558 help: help_string,
558 559 help_index: help_index}
559 560 );
560 561 }
561 562 }
562 563 help.sort(function (a, b) {
563 564 if (a.help_index > b.help_index)
564 565 return 1;
565 566 if (a.help_index < b.help_index)
566 567 return -1;
567 568 return 0;
568 569 });
569 570 return help;
570 571 }
571 572
572 573 ShortcutManager.prototype.normalize_key = function (key) {
573 574 return inv_keycodes[keycodes[key]];
574 575 }
575 576
576 577 ShortcutManager.prototype.normalize_shortcut = function (shortcut) {
577 578 // Sort a sequence of + separated modifiers into the order alt+ctrl+meta+shift
578 579 shortcut = shortcut.replace('cmd', 'meta').toLowerCase();
579 580 var values = shortcut.split("+");
580 581 if (values.length === 1) {
581 582 return this.normalize_key(values[0])
582 583 } else {
583 584 var modifiers = values.slice(0,-1);
584 585 var key = this.normalize_key(values[values.length-1]);
585 586 modifiers.sort();
586 587 return modifiers.join('+') + '+' + key;
587 588 }
588 589 }
589 590
590 591 ShortcutManager.prototype.event_to_shortcut = function (event) {
591 592 // Convert a jQuery keyboard event to a strong based keyboard shortcut
592 593 var shortcut = '';
593 594 var key = inv_keycodes[event.which]
594 595 if (event.altKey && key !== 'alt') {shortcut += 'alt+';}
595 596 if (event.ctrlKey && key !== 'ctrl') {shortcut += 'ctrl+';}
596 597 if (event.metaKey && key !== 'meta') {shortcut += 'meta+';}
597 598 if (event.shiftKey && key !== 'shift') {shortcut += 'shift+';}
598 599 shortcut += key;
599 600 return shortcut
600 601 }
601 602
602 603 ShortcutManager.prototype.clear_shortcuts = function () {
603 604 this._shortcuts = {};
604 605 }
605 606
606 607 ShortcutManager.prototype.add_shortcut = function (shortcut, data) {
607 608 if (typeof(data) === 'function') {
608 609 data = {help: '', help_index: '', handler: data}
609 610 }
610 611 data.help_index = data.help_index || '';
611 612 data.help = data.help || '';
612 613 data.count = data.count || 1;
613 614 if (data.help_index === '') {
614 615 data.help_index = 'zz';
615 616 }
616 617 shortcut = this.normalize_shortcut(shortcut);
617 618 this._counts[shortcut] = 0;
618 619 this._shortcuts[shortcut] = data;
619 620 }
620 621
621 622 ShortcutManager.prototype.add_shortcuts = function (data) {
622 623 for (var shortcut in data) {
623 624 this.add_shortcut(shortcut, data[shortcut]);
624 625 }
625 626 }
626 627
627 628 ShortcutManager.prototype.remove_shortcut = function (shortcut) {
628 629 shortcut = this.normalize_shortcut(shortcut);
629 630 delete this._counts[shortcut];
630 631 delete this._shortcuts[shortcut];
631 632 }
632 633
633 634 ShortcutManager.prototype.count_handler = function (shortcut, event, data) {
634 635 var that = this;
635 636 var c = this._counts;
637 var t = this._timers;
638 var timer = null;
636 639 if (c[shortcut] === data.count-1) {
637 640 c[shortcut] = 0;
641 var timer = t[shortcut];
642 if (timer) {clearTimeout(timer); delete t[shortcut];}
638 643 return data.handler(event);
639 644 } else {
640 645 c[shortcut] = c[shortcut] + 1;
641 setTimeout(function () {
646 timer = setTimeout(function () {
642 647 c[shortcut] = 0;
643 648 }, that.delay);
649 t[shortcut] = timer;
644 650 }
645 651 return false;
646
647 652 }
648 653
649 654 ShortcutManager.prototype.call_handler = function (event) {
650 655 var shortcut = this.event_to_shortcut(event);
651 656 var data = this._shortcuts[shortcut];
652 657 if (data) {
653 658 var handler = data['handler'];
654 659 if (handler) {
655 660 if (data.count === 1) {
656 661 return handler(event);
657 662 } else if (data.count > 1) {
658 663 return this.count_handler(shortcut, event, data);
659 664 }
660 665 }
661 666 }
662 667 return true;
663 668 }
664 669
665 670
666 671
667 672 // Main keyboard manager for the notebook
668 673
669 674 var KeyboardManager = function () {
670 675 this.mode = 'command';
671 676 this.enabled = true;
672 677 this.bind_events();
673 678 this.command_shortcuts = new ShortcutManager();
674 679 this.command_shortcuts.add_shortcuts(default_common_shortcuts);
675 680 this.command_shortcuts.add_shortcuts(default_command_shortcuts);
676 681 this.edit_shortcuts = new ShortcutManager();
677 682 this.edit_shortcuts.add_shortcuts(default_common_shortcuts);
678 683 this.edit_shortcuts.add_shortcuts(default_edit_shortcuts);
679 684 };
680 685
681 686 KeyboardManager.prototype.bind_events = function () {
682 687 var that = this;
683 688 $(document).keydown(function (event) {
684 689 return that.handle_keydown(event);
685 690 });
686 691 };
687 692
688 693 KeyboardManager.prototype.handle_keydown = function (event) {
689 694 var notebook = IPython.notebook;
690 695
691 696 if (event.which === keycodes['esc']) {
692 697 // Intercept escape at highest level to avoid closing
693 698 // websocket connection with firefox
694 699 event.preventDefault();
695 700 }
696 701
697 702 if (!this.enabled) {
698 703 if (event.which === keycodes['esc']) {
699 704 // ESC
700 705 notebook.command_mode();
701 706 return false;
702 707 }
703 708 return true;
704 709 }
705 710
706 711 if (this.mode === 'edit') {
707 712 return this.edit_shortcuts.call_handler(event);
708 713 } else if (this.mode === 'command') {
709 714 return this.command_shortcuts.call_handler(event);
710 715 }
711 716 return true;
712 717 }
713 718
714 719 KeyboardManager.prototype.edit_mode = function () {
715 720 this.last_mode = this.mode;
716 721 this.mode = 'edit';
717 722 }
718 723
719 724 KeyboardManager.prototype.command_mode = function () {
720 725 this.last_mode = this.mode;
721 726 this.mode = 'command';
722 727 }
723 728
724 729 KeyboardManager.prototype.enable = function () {
725 730 this.enabled = true;
726 731 }
727 732
728 733 KeyboardManager.prototype.disable = function () {
729 734 this.enabled = false;
730 735 }
731 736
732 737 KeyboardManager.prototype.register_events = function (e) {
733 738 var that = this;
734 739 e.on('focusin', function () {
735 740 that.disable();
736 741 });
737 742 e.on('focusout', function () {
738 743 that.enable();
739 744 });
740 745 // There are times (raw_input) where we remove the element from the DOM before
741 746 // focusout is called. In this case we bind to the remove event of jQueryUI,
742 747 // which gets triggered upon removal.
743 748 e.on('remove', function () {
744 749 that.enable();
745 750 });
746 751 }
747 752
748 753
749 754 IPython.keycodes = keycodes;
750 755 IPython.inv_keycodes = inv_keycodes;
751 756 IPython.default_common_shortcuts = default_common_shortcuts;
752 757 IPython.default_edit_shortcuts = default_edit_shortcuts;
753 758 IPython.default_command_shortcuts = default_command_shortcuts;
754 759 IPython.ShortcutManager = ShortcutManager;
755 760 IPython.KeyboardManager = KeyboardManager;
756 761
757 762 return IPython;
758 763
759 764 }(IPython));
@@ -1,50 +1,47 b''
1 1 div.cell {
2 2 border: 1px solid transparent;
3 3 .vbox();
4 4
5 5 &.selected {
6 6 .corner-all;
7 7 border : thin @border_color solid;
8 8 }
9 9
10 10 &.edit_mode {
11 11 .corner-all;
12 12 border : thin green solid;
13 13 }
14 14 }
15 15
16 16 div.cell {
17 17 width: 100%;
18 18 padding: 5px 5px 5px 0px;
19 19 /* This acts as a spacer between cells, that is outside the border */
20 20 margin: 0px;
21 21 outline: none;
22 22 }
23 23
24 24 div.prompt {
25 25 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
26 26 min-width: 11ex;
27 27 /* This padding is tuned to match the padding on the CodeMirror editor. */
28 28 padding: @code_padding;
29 29 margin: 0px;
30 30 font-family: @monoFontFamily;
31 31 text-align: right;
32 32 /* This has to match that of the the CodeMirror class line-height below */
33 33 line-height: @code_line_height;
34 34 }
35 35
36 36 div.inner_cell {
37 37 .vbox();
38 38 .box-flex1();
39
40 /* This is required for FF to add scrollbars when code cells overflow. */
41 overflow: auto;
42 39 }
43 40
44 41 /* This is needed so that empty prompt areas can collapse to zero height when there
45 42 is no content in the output_subarea and the prompt. The main purpose of this is
46 43 to make sure that empty JavaScript output_subareas have no height. */
47 44 div.prompt:empty {
48 45 padding-top: 0;
49 46 padding-bottom: 0;
50 47 }
@@ -1,58 +1,58 b''
1 1 /* The following gets added to the <head> if it is detected that the user has a
2 2 * monospace font with inconsistent normal/bold/italic height. See
3 3 * notebookmain.js. Such fonts will have keywords vertically offset with
4 4 * respect to the rest of the text. The user should select a better font.
5 5 * See: https://github.com/ipython/ipython/issues/1503
6 6 *
7 7 * .CodeMirror span {
8 8 * vertical-align: bottom;
9 9 * }
10 10 */
11 11
12 12 .CodeMirror {
13 13 line-height: @code_line_height; /* Changed from 1em to our global default */
14 14 height: auto; /* Changed to auto to autogrow */
15 15 background: none; /* Changed from white to allow our bg to show through */
16 16 }
17 17
18 18 .CodeMirror-scroll {
19 19 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
20 20 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
21 21 overflow-y: hidden;
22 22 overflow-x: auto;
23 23 }
24 24
25 @-moz-document url-prefix() {
25 @-moz-document {
26 26 /* Firefox does weird and terrible things (#3549) when overflow-x is auto */
27 27 /* It doesn't respect the overflow setting anyway, so we can workaround it with this */
28 28 .CodeMirror-scroll {
29 29 overflow-x: hidden;
30 30 }
31 31 }
32 32
33 33 .CodeMirror-lines {
34 34 /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */
35 35 /* we have set a different line-height and want this to scale with that. */
36 36 padding: @code_padding;
37 37 }
38 38
39 39 .CodeMirror-linenumber {
40 40 // This is needed to fine tune the position of the line numbers because we use the 0.4em in @code_padding
41 41 // spacing in various places. Fine tuned to look right.
42 42 padding: 0 8px 0 4px;
43 43 }
44 44
45 45 .CodeMirror-gutters {
46 46 // This is needed because our cell has rounded corners, otherwise the gutter area square
47 47 // corner cuts into the rounded cell border.
48 48 border-bottom-left-radius: @baseBorderRadius;
49 49 border-top-left-radius: @baseBorderRadius;
50 50 }
51 51
52 52 .CodeMirror pre {
53 53 /* In CM3 this went to 4px from 0 in CM2. We need the 0 value because of how we size */
54 54 /* .CodeMirror-lines */
55 55 padding: 0;
56 56 border: 0;
57 57 .border-radius(0)
58 58 }
@@ -1,195 +1,195 b''
1 1 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
2 2 .clearfix:after{clear:both}
3 3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
4 4 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
5 5 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
6 6 .corner-all{border-radius:4px}
7 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
8 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
9 .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%}
10 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
11 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
12 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
13 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
14 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
15 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
7 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
8 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
9 .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%;display:flex;flex-direction:column;align-items:stretch}
10 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
11 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse}
12 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
13 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
14 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
15 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
16 16 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
17 17 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
18 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start}
19 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end}
20 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center}
21 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start}
22 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end}
23 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center}
18 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start}
19 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end}
20 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center}
21 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start}
22 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end}
23 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center}
24 24 div.error{margin:2em;text-align:center}
25 25 div.error>h1{font-size:500%;line-height:normal}
26 26 div.error>p{font-size:200%;line-height:normal}
27 27 div.traceback-wrapper{text-align:left;max-width:800px;margin:auto}
28 28 .center-nav{display:inline-block;margin-bottom:-4px}
29 29 .alternate_upload{background-color:none;display:inline}
30 30 .alternate_upload.form{padding:0;margin:0}
31 31 .alternate_upload input.fileinput{background-color:#f00;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;height:26px}
32 32 ul#tabs{margin-bottom:4px}
33 33 ul#tabs a{padding-top:4px;padding-bottom:4px}
34 34 ul.breadcrumb a:focus,ul.breadcrumb a:hover{text-decoration:none}
35 35 ul.breadcrumb i.icon-home{font-size:16px;margin-right:4px}
36 36 ul.breadcrumb span{color:#5e5e5e}
37 37 .list_toolbar{padding:4px 0 4px 0}
38 38 .list_toolbar [class*="span"]{min-height:26px}
39 39 .list_header{font-weight:bold}
40 40 .list_container{margin-top:4px;margin-bottom:20px;border:1px solid #ababab;border-radius:4px}
41 41 .list_container>div{border-bottom:1px solid #ababab}.list_container>div:hover .list-item{background-color:#f00}
42 42 .list_container>div:last-child{border:none}
43 43 .list_item:hover .list_item{background-color:#ddd}
44 44 .list_item a{text-decoration:none}
45 45 .list_header>div,.list_item>div{padding-top:4px;padding-bottom:4px;padding-left:7px;padding-right:7px;height:22px;line-height:22px}
46 46 .item_name{line-height:22px;height:26px}
47 47 .item_icon{font-size:14px;color:#5e5e5e;margin-right:7px}
48 48 .item_buttons{line-height:1em}
49 49 .toolbar_info{height:26px;line-height:26px}
50 50 input.nbname_input,input.engine_num_input{padding-top:3px;padding-bottom:3px;height:14px;line-height:14px;margin:0}
51 51 input.engine_num_input{width:60px}
52 52 .highlight_text{color:#00f}
53 53 #project_name>.breadcrumb{padding:0;margin-bottom:0;background-color:transparent;font-weight:bold}
54 54 .ansibold{font-weight:bold}
55 55 .ansiblack{color:#000}
56 56 .ansired{color:#8b0000}
57 57 .ansigreen{color:#006400}
58 58 .ansiyellow{color:#a52a2a}
59 59 .ansiblue{color:#00008b}
60 60 .ansipurple{color:#9400d3}
61 61 .ansicyan{color:#4682b4}
62 62 .ansigray{color:#808080}
63 63 .ansibgblack{background-color:#000}
64 64 .ansibgred{background-color:#f00}
65 65 .ansibggreen{background-color:#008000}
66 66 .ansibgyellow{background-color:#ff0}
67 67 .ansibgblue{background-color:#00f}
68 68 .ansibgpurple{background-color:#f0f}
69 69 .ansibgcyan{background-color:#0ff}
70 70 .ansibggray{background-color:#808080}
71 div.cell{border:1px solid transparent;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%}div.cell.selected{border-radius:4px;border:thin #ababab solid}
71 div.cell{border:1px solid transparent;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%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid}
72 72 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
73 73 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
74 74 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
75 div.inner_cell{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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;overflow:auto}
75 div.inner_cell{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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
76 76 div.prompt:empty{padding-top:0;padding-bottom:0}
77 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
77 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
78 78 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
79 79 div.input_prompt{color:#000080;border-top:1px solid transparent}
80 80 .CodeMirror{line-height:1.231em;height:auto;background:none;}
81 81 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
82 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
82 @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
83 83 .CodeMirror-linenumber{padding:0 8px 0 4px}
84 84 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
85 85 .CodeMirror pre{padding:0;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
86 86 pre code{display:block;padding:.5em}
87 87 .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:#000}
88 88 .highlight-string,pre .string,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#ba2121}
89 89 .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic}
90 90 .highlight-number,pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080}
91 91 pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#88f}
92 92 .highlight-keyword,pre .keyword,pre .id,pre .phpdoc,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{color:#008000;font-weight:bold}
93 93 .highlight-builtin,pre .built_in{color:#008000}
94 94 pre .markdown .emphasis{font-style:italic}
95 95 pre .nginx .built_in{font-weight:normal}
96 96 pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:.5}
97 97 .cm-s-ipython span.cm-variable{color:#000}
98 98 .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold}
99 99 .cm-s-ipython span.cm-number{color:#080}
100 100 .cm-s-ipython span.cm-comment{color:#408080;font-style:italic}
101 101 .cm-s-ipython span.cm-string{color:#ba2121}
102 102 .cm-s-ipython span.cm-builtin{color:#008000}
103 103 .cm-s-ipython span.cm-error{color:#f00}
104 104 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
105 105 .cm-s-ipython span.cm-meta{color:#a2f}
106 106 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
107 div.output_wrapper{position:relative;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%}
107 div.output_wrapper{position:relative;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%;display:flex;flex-direction:column;align-items:stretch}
108 108 div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);-moz-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);box-shadow:inset 0 2px 8px rgba(0,0,0,0.8)}
109 div.output_collapsed{margin:0;padding:0;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%}
109 div.output_collapsed{margin:0;padding:0;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%;display:flex;flex-direction:column;align-items:stretch}
110 110 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
111 111 div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)}
112 112 div.output_prompt{color:#8b0000}
113 div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}div.output_area .MathJax_Display{text-align:left !important}
113 div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important}
114 114 div.output_area .rendered_html table{margin-left:0;margin-right:0}
115 115 div.output_area .rendered_html img{margin-left:0;margin-right:0}
116 .output{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%}
116 .output{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%;display:flex;flex-direction:column;align-items:stretch}
117 117 div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit}
118 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
118 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
119 119 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
120 120 div.output_stderr{background:#fdd;}
121 121 div.output_latex{text-align:left}
122 122 div.output_javascript:empty{padding:0}
123 123 .js-error{color:#8b0000}
124 124 div.raw_input{padding-top:0;padding-bottom:0;height:1em;line-height:1em;font-family:monospace}
125 125 span.input_prompt{font-family:inherit}
126 126 input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;margin:-2px 0 0 1px;padding-left:1px;padding-top:2px;height:1em}
127 127 p.p-space{margin-bottom:10px}
128 128 .rendered_html{color:#000;}.rendered_html em{font-style:italic}
129 129 .rendered_html strong{font-weight:bold}
130 130 .rendered_html u{text-decoration:underline}
131 131 .rendered_html :link{text-decoration:underline}
132 132 .rendered_html :visited{text-decoration:underline}
133 133 .rendered_html h1{font-size:185.7%;margin:1.08em 0 0 0;font-weight:bold;line-height:1}
134 134 .rendered_html h2{font-size:157.1%;margin:1.27em 0 0 0;font-weight:bold;line-height:1}
135 135 .rendered_html h3{font-size:128.6%;margin:1.55em 0 0 0;font-weight:bold;line-height:1}
136 136 .rendered_html h4{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1}
137 137 .rendered_html h5{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic}
138 138 .rendered_html h6{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic}
139 139 .rendered_html h1:first-child{margin-top:.538em}
140 140 .rendered_html h2:first-child{margin-top:.636em}
141 141 .rendered_html h3:first-child{margin-top:.777em}
142 142 .rendered_html h4:first-child{margin-top:1em}
143 143 .rendered_html h5:first-child{margin-top:1em}
144 144 .rendered_html h6:first-child{margin-top:1em}
145 145 .rendered_html ul{list-style:disc;margin:0 2em}
146 146 .rendered_html ul ul{list-style:square;margin:0 2em}
147 147 .rendered_html ul ul ul{list-style:circle;margin:0 2em}
148 148 .rendered_html ol{list-style:decimal;margin:0 2em}
149 149 .rendered_html ol ol{list-style:upper-alpha;margin:0 2em}
150 150 .rendered_html ol ol ol{list-style:lower-alpha;margin:0 2em}
151 151 .rendered_html ol ol ol ol{list-style:lower-roman;margin:0 2em}
152 152 .rendered_html ol ol ol ol ol{list-style:decimal;margin:0 2em}
153 153 .rendered_html *+ul{margin-top:1em}
154 154 .rendered_html *+ol{margin-top:1em}
155 155 .rendered_html hr{color:#000;background-color:#000}
156 156 .rendered_html pre{margin:1em 2em}
157 157 .rendered_html pre,.rendered_html code{border:0;background-color:#fff;color:#000;font-size:100%;padding:0}
158 158 .rendered_html blockquote{margin:1em 2em}
159 159 .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid #000;border-collapse:collapse}
160 160 .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid #000;border-collapse:collapse;margin:1em 2em}
161 161 .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px}
162 162 .rendered_html th{font-weight:bold}
163 163 .rendered_html *+table{margin-top:1em}
164 164 .rendered_html p{text-align:justify}
165 165 .rendered_html *+p{margin-top:1em}
166 166 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
167 167 .rendered_html *+img{margin-top:1em}
168 div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
168 div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
169 169 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
170 170 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
171 171 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
172 172 h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible}
173 173 div.cell.text_cell.rendered{padding:0}
174 .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
174 .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
175 175 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
176 176 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
177 177 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
178 178 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
179 179 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
180 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
181 .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
180 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
181 .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
182 182 .widget-text{width:350px;margin-bottom:0}
183 183 .widget-listbox{width:364px;margin-bottom:0}
184 184 .widget-numeric-text{width:150px}
185 185 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
186 186 .widget-combo-btn{min-width:138px;}
187 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
188 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
189 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;height:30px}
190 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%}
191 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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:30px}
187 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
188 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
189 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;height:30px}
190 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch}
191 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;width:30px}
192 192 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
193 193 .widget-modal-body{max-height:none !important}
194 194 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
195 195 .docked-widget-modal{overflow:hidden;position:relative !important;top:0 !important;left:0 !important;margin-left:0 !important}
@@ -1,1526 +1,1526 b''
1 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
2 .clearfix:after{clear:both}
3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
4 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
5 1 article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}
6 2 audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
7 3 audio:not([controls]){display:none}
8 4 html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}
9 5 a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}
10 6 a:hover,a:active{outline:0}
11 7 sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}
12 8 sup{top:-0.5em}
13 9 sub{bottom:-0.25em}
14 10 img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}
15 11 #map_canvas img,.google-maps img{max-width:none}
16 12 button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}
17 13 button,input{*overflow:visible;line-height:normal}
18 14 button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}
19 15 button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
20 16 label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}
21 17 input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}
22 18 input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}
23 19 textarea{overflow:auto;vertical-align:top}
24 20 @media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important} a,a:visited{text-decoration:underline} a[href]:after{content:" (" attr(href) ")"} abbr[title]:after{content:" (" attr(title) ")"} .ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""} pre,blockquote{border:1px solid #999;page-break-inside:avoid} thead{display:table-header-group} tr,img{page-break-inside:avoid} img{max-width:100% !important} @page {margin:.5cm}p,h2,h3{orphans:3;widows:3} h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:20px;color:#000;background-color:#fff}
25 21 a{color:#08c;text-decoration:none}
26 22 a:hover,a:focus{color:#005580;text-decoration:underline}
27 23 .img-rounded{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}
28 24 .img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}
29 25 .img-circle{border-radius:500px;-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}
30 26 .row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}
31 27 .row:after{clear:both}
32 28 [class*="span"]{float:left;min-height:1px;margin-left:20px}
33 29 .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}
34 30 .span12{width:940px}
35 31 .span11{width:860px}
36 32 .span10{width:780px}
37 33 .span9{width:700px}
38 34 .span8{width:620px}
39 35 .span7{width:540px}
40 36 .span6{width:460px}
41 37 .span5{width:380px}
42 38 .span4{width:300px}
43 39 .span3{width:220px}
44 40 .span2{width:140px}
45 41 .span1{width:60px}
46 42 .offset12{margin-left:980px}
47 43 .offset11{margin-left:900px}
48 44 .offset10{margin-left:820px}
49 45 .offset9{margin-left:740px}
50 46 .offset8{margin-left:660px}
51 47 .offset7{margin-left:580px}
52 48 .offset6{margin-left:500px}
53 49 .offset5{margin-left:420px}
54 50 .offset4{margin-left:340px}
55 51 .offset3{margin-left:260px}
56 52 .offset2{margin-left:180px}
57 53 .offset1{margin-left:100px}
58 54 .row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}
59 55 .row-fluid:after{clear:both}
60 56 .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%}
61 57 .row-fluid [class*="span"]:first-child{margin-left:0}
62 58 .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}
63 59 .row-fluid .span12{width:100%;*width:99.94680851063829%}
64 60 .row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}
65 61 .row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}
66 62 .row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}
67 63 .row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}
68 64 .row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}
69 65 .row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}
70 66 .row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}
71 67 .row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}
72 68 .row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}
73 69 .row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}
74 70 .row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}
75 71 .row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}
76 72 .row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}
77 73 .row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}
78 74 .row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}
79 75 .row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}
80 76 .row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}
81 77 .row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}
82 78 .row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}
83 79 .row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}
84 80 .row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}
85 81 .row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}
86 82 .row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}
87 83 .row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}
88 84 .row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}
89 85 .row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}
90 86 .row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}
91 87 .row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}
92 88 .row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}
93 89 .row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}
94 90 .row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}
95 91 .row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}
96 92 .row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}
97 93 .row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}
98 94 .row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}
99 95 [class*="span"].hide,.row-fluid [class*="span"].hide{display:none}
100 96 [class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}
101 97 .container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0}
102 98 .container:after{clear:both}
103 99 .container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0}
104 100 .container-fluid:after{clear:both}
105 101 p{margin:0 0 10px}
106 102 .lead{margin-bottom:20px;font-size:19.5px;font-weight:200;line-height:30px}
107 103 small{font-size:85%}
108 104 strong{font-weight:bold}
109 105 em{font-style:italic}
110 106 cite{font-style:normal}
111 107 .muted{color:#999}
112 108 a.muted:hover,a.muted:focus{color:#808080}
113 109 .text-warning{color:#c09853}
114 110 a.text-warning:hover,a.text-warning:focus{color:#a47e3c}
115 111 .text-error{color:#b94a48}
116 112 a.text-error:hover,a.text-error:focus{color:#953b39}
117 113 .text-info{color:#3a87ad}
118 114 a.text-info:hover,a.text-info:focus{color:#2d6987}
119 115 .text-success{color:#468847}
120 116 a.text-success:hover,a.text-success:focus{color:#356635}
121 117 .text-left{text-align:left}
122 118 .text-right{text-align:right}
123 119 .text-center{text-align:center}
124 120 h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}
125 121 h1,h2,h3{line-height:40px}
126 122 h1{font-size:35.75px}
127 123 h2{font-size:29.25px}
128 124 h3{font-size:22.75px}
129 125 h4{font-size:16.25px}
130 126 h5{font-size:13px}
131 127 h6{font-size:11.049999999999999px}
132 128 h1 small{font-size:22.75px}
133 129 h2 small{font-size:16.25px}
134 130 h3 small{font-size:13px}
135 131 h4 small{font-size:13px}
136 132 .page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}
137 133 ul,ol{padding:0;margin:0 0 10px 25px}
138 134 ul ul,ul ol,ol ol,ol ul{margin-bottom:0}
139 135 li{line-height:20px}
140 136 ul.unstyled,ol.unstyled{margin-left:0;list-style:none}
141 137 ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px}
142 138 dl{margin-bottom:20px}
143 139 dt,dd{line-height:20px}
144 140 dt{font-weight:bold}
145 141 dd{margin-left:10px}
146 142 .dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0}
147 143 .dl-horizontal:after{clear:both}
148 144 .dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
149 145 .dl-horizontal dd{margin-left:180px}
150 146 hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}
151 147 abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}
152 148 abbr.initialism{font-size:90%;text-transform:uppercase}
153 149 blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16.25px;font-weight:300;line-height:1.25}
154 150 blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}
155 151 blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}
156 152 blockquote.pull-right small:before{content:''}
157 153 blockquote.pull-right small:after{content:'\00A0 \2014'}
158 154 q:before,q:after,blockquote:before,blockquote:after{content:""}
159 155 address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}
160 156 code,pre{padding:0 3px 2px;font-family:monospace;font-size:11px;color:#333;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
161 157 code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap}
162 158 pre{display:block;padding:9.5px;margin:0 0 10px;font-size:12px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}
163 159 pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}
164 160 .pre-scrollable{max-height:340px;overflow-y:scroll}
165 161 form{margin:0 0 20px}
166 162 fieldset{padding:0;margin:0;border:0}
167 163 legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:19.5px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}
168 164 label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:20px}
169 165 input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}
170 166 label{display:block;margin-bottom:5px}
171 167 select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:13px;line-height:20px;color:#555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle}
172 168 input,textarea,.uneditable-input{width:206px}
173 169 textarea{height:auto}
174 170 textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-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 linear .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)}
175 171 input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal}
176 172 input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}
177 173 select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}
178 174 select{width:220px;border:1px solid #ccc;background-color:#fff}
179 175 select[multiple],select[size]{height:auto}
180 176 select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}
181 177 .uneditable-input,.uneditable-textarea{color:#999;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);cursor:not-allowed}
182 178 .uneditable-input{overflow:hidden;white-space:nowrap}
183 179 .uneditable-textarea{width:auto;height:auto}
184 180 input:-moz-placeholder,textarea:-moz-placeholder{color:#999}
185 181 input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}
186 182 input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}
187 183 .radio,.checkbox{min-height:20px;padding-left:20px}
188 184 .radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}
189 185 .controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}
190 186 .radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}
191 187 .radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}
192 188 .input-mini{width:60px}
193 189 .input-small{width:90px}
194 190 .input-medium{width:150px}
195 191 .input-large{width:210px}
196 192 .input-xlarge{width:270px}
197 193 .input-xxlarge{width:530px}
198 194 input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}
199 195 .input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}
200 196 input,textarea,.uneditable-input{margin-left:0}
201 197 .controls-row [class*="span"]+[class*="span"]{margin-left:20px}
202 198 input.span12,textarea.span12,.uneditable-input.span12{width:926px}
203 199 input.span11,textarea.span11,.uneditable-input.span11{width:846px}
204 200 input.span10,textarea.span10,.uneditable-input.span10{width:766px}
205 201 input.span9,textarea.span9,.uneditable-input.span9{width:686px}
206 202 input.span8,textarea.span8,.uneditable-input.span8{width:606px}
207 203 input.span7,textarea.span7,.uneditable-input.span7{width:526px}
208 204 input.span6,textarea.span6,.uneditable-input.span6{width:446px}
209 205 input.span5,textarea.span5,.uneditable-input.span5{width:366px}
210 206 input.span4,textarea.span4,.uneditable-input.span4{width:286px}
211 207 input.span3,textarea.span3,.uneditable-input.span3{width:206px}
212 208 input.span2,textarea.span2,.uneditable-input.span2{width:126px}
213 209 input.span1,textarea.span1,.uneditable-input.span1{width:46px}
214 210 .controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0}
215 211 .controls-row:after{clear:both}
216 212 .controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}
217 213 .controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}
218 214 input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}
219 215 input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}
220 216 .control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}
221 217 .control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}
222 218 .control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}
223 219 .control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}
224 220 .control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}
225 221 .control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}
226 222 .control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}
227 223 .control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}
228 224 .control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}
229 225 .control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}
230 226 .control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}
231 227 .control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}
232 228 .control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}
233 229 .control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}
234 230 .control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}
235 231 .control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}
236 232 input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}
237 233 .form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0}
238 234 .form-actions:after{clear:both}
239 235 .help-block,.help-inline{color:#262626}
240 236 .help-block{display:block;margin-bottom:10px}
241 237 .help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px}
242 238 .input-append,.input-prepend{display:inline-block;margin-bottom:10px;vertical-align:middle;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:13px}
243 239 .input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}
244 240 .input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:13px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}
245 241 .input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
246 242 .input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}
247 243 .input-prepend .add-on,.input-prepend .btn{margin-right:-1px}
248 244 .input-prepend .add-on:first-child,.input-prepend .btn:first-child{border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
249 245 .input-append input,.input-append select,.input-append .uneditable-input{border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}
250 246 .input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}
251 247 .input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}
252 248 .input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}
253 249 .input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
254 250 .input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}
255 251 .input-prepend.input-append .btn-group:first-child{margin-left:0}
256 252 input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}
257 253 .form-search .input-append .search-query,.form-search .input-prepend .search-query{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
258 254 .form-search .input-append .search-query{border-radius:14px 0 0 14px;-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}
259 255 .form-search .input-append .btn{border-radius:0 14px 14px 0;-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}
260 256 .form-search .input-prepend .search-query{border-radius:0 14px 14px 0;-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}
261 257 .form-search .input-prepend .btn{border-radius:14px 0 0 14px;-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}
262 258 .form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle}
263 259 .form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}
264 260 .form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}
265 261 .form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}
266 262 .form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}
267 263 .form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}
268 264 .control-group{margin-bottom:10px}
269 265 legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}
270 266 .form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0}
271 267 .form-horizontal .control-group:after{clear:both}
272 268 .form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}
273 269 .form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}
274 270 .form-horizontal .help-block{margin-bottom:0}
275 271 .form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}
276 272 .form-horizontal .form-actions{padding-left:180px}
277 273 table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}
278 274 .table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}
279 275 .table th{font-weight:bold}
280 276 .table thead th{vertical-align:bottom}
281 277 .table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}
282 278 .table tbody+tbody{border-top:2px solid #ddd}
283 279 .table .table{background-color:#fff}
284 280 .table-condensed th,.table-condensed td{padding:4px 5px}
285 281 .table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}
286 282 .table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}
287 283 .table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}
288 284 .table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}
289 285 .table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}
290 286 .table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}
291 287 .table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}
292 288 .table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}
293 289 .table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}
294 290 .table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px}
295 291 .table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}
296 292 .table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}
297 293 table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}
298 294 .table td.span1,.table th.span1{float:none;width:44px;margin-left:0}
299 295 .table td.span2,.table th.span2{float:none;width:124px;margin-left:0}
300 296 .table td.span3,.table th.span3{float:none;width:204px;margin-left:0}
301 297 .table td.span4,.table th.span4{float:none;width:284px;margin-left:0}
302 298 .table td.span5,.table th.span5{float:none;width:364px;margin-left:0}
303 299 .table td.span6,.table th.span6{float:none;width:444px;margin-left:0}
304 300 .table td.span7,.table th.span7{float:none;width:524px;margin-left:0}
305 301 .table td.span8,.table th.span8{float:none;width:604px;margin-left:0}
306 302 .table td.span9,.table th.span9{float:none;width:684px;margin-left:0}
307 303 .table td.span10,.table th.span10{float:none;width:764px;margin-left:0}
308 304 .table td.span11,.table th.span11{float:none;width:844px;margin-left:0}
309 305 .table td.span12,.table th.span12{float:none;width:924px;margin-left:0}
310 306 .table tbody tr.success>td{background-color:#dff0d8}
311 307 .table tbody tr.error>td{background-color:#f2dede}
312 308 .table tbody tr.warning>td{background-color:#fcf8e3}
313 309 .table tbody tr.info>td{background-color:#d9edf7}
314 310 .table-hover tbody tr.success:hover>td{background-color:#d0e9c6}
315 311 .table-hover tbody tr.error:hover>td{background-color:#ebcccc}
316 312 .table-hover tbody tr.warning:hover>td{background-color:#faf2cc}
317 313 .table-hover tbody tr.info:hover>td{background-color:#c4e3f3}
318 314 [class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;margin-top:1px}
319 315 .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}
320 316 .icon-glass{background-position:0 0}
321 317 .icon-music{background-position:-24px 0}
322 318 .icon-search{background-position:-48px 0}
323 319 .icon-envelope{background-position:-72px 0}
324 320 .icon-heart{background-position:-96px 0}
325 321 .icon-star{background-position:-120px 0}
326 322 .icon-star-empty{background-position:-144px 0}
327 323 .icon-user{background-position:-168px 0}
328 324 .icon-film{background-position:-192px 0}
329 325 .icon-th-large{background-position:-216px 0}
330 326 .icon-th{background-position:-240px 0}
331 327 .icon-th-list{background-position:-264px 0}
332 328 .icon-ok{background-position:-288px 0}
333 329 .icon-remove{background-position:-312px 0}
334 330 .icon-zoom-in{background-position:-336px 0}
335 331 .icon-zoom-out{background-position:-360px 0}
336 332 .icon-off{background-position:-384px 0}
337 333 .icon-signal{background-position:-408px 0}
338 334 .icon-cog{background-position:-432px 0}
339 335 .icon-trash{background-position:-456px 0}
340 336 .icon-home{background-position:0 -24px}
341 337 .icon-file{background-position:-24px -24px}
342 338 .icon-time{background-position:-48px -24px}
343 339 .icon-road{background-position:-72px -24px}
344 340 .icon-download-alt{background-position:-96px -24px}
345 341 .icon-download{background-position:-120px -24px}
346 342 .icon-upload{background-position:-144px -24px}
347 343 .icon-inbox{background-position:-168px -24px}
348 344 .icon-play-circle{background-position:-192px -24px}
349 345 .icon-repeat{background-position:-216px -24px}
350 346 .icon-refresh{background-position:-240px -24px}
351 347 .icon-list-alt{background-position:-264px -24px}
352 348 .icon-lock{background-position:-287px -24px}
353 349 .icon-flag{background-position:-312px -24px}
354 350 .icon-headphones{background-position:-336px -24px}
355 351 .icon-volume-off{background-position:-360px -24px}
356 352 .icon-volume-down{background-position:-384px -24px}
357 353 .icon-volume-up{background-position:-408px -24px}
358 354 .icon-qrcode{background-position:-432px -24px}
359 355 .icon-barcode{background-position:-456px -24px}
360 356 .icon-tag{background-position:0 -48px}
361 357 .icon-tags{background-position:-25px -48px}
362 358 .icon-book{background-position:-48px -48px}
363 359 .icon-bookmark{background-position:-72px -48px}
364 360 .icon-print{background-position:-96px -48px}
365 361 .icon-camera{background-position:-120px -48px}
366 362 .icon-font{background-position:-144px -48px}
367 363 .icon-bold{background-position:-167px -48px}
368 364 .icon-italic{background-position:-192px -48px}
369 365 .icon-text-height{background-position:-216px -48px}
370 366 .icon-text-width{background-position:-240px -48px}
371 367 .icon-align-left{background-position:-264px -48px}
372 368 .icon-align-center{background-position:-288px -48px}
373 369 .icon-align-right{background-position:-312px -48px}
374 370 .icon-align-justify{background-position:-336px -48px}
375 371 .icon-list{background-position:-360px -48px}
376 372 .icon-indent-left{background-position:-384px -48px}
377 373 .icon-indent-right{background-position:-408px -48px}
378 374 .icon-facetime-video{background-position:-432px -48px}
379 375 .icon-picture{background-position:-456px -48px}
380 376 .icon-pencil{background-position:0 -72px}
381 377 .icon-map-marker{background-position:-24px -72px}
382 378 .icon-adjust{background-position:-48px -72px}
383 379 .icon-tint{background-position:-72px -72px}
384 380 .icon-edit{background-position:-96px -72px}
385 381 .icon-share{background-position:-120px -72px}
386 382 .icon-check{background-position:-144px -72px}
387 383 .icon-move{background-position:-168px -72px}
388 384 .icon-step-backward{background-position:-192px -72px}
389 385 .icon-fast-backward{background-position:-216px -72px}
390 386 .icon-backward{background-position:-240px -72px}
391 387 .icon-play{background-position:-264px -72px}
392 388 .icon-pause{background-position:-288px -72px}
393 389 .icon-stop{background-position:-312px -72px}
394 390 .icon-forward{background-position:-336px -72px}
395 391 .icon-fast-forward{background-position:-360px -72px}
396 392 .icon-step-forward{background-position:-384px -72px}
397 393 .icon-eject{background-position:-408px -72px}
398 394 .icon-chevron-left{background-position:-432px -72px}
399 395 .icon-chevron-right{background-position:-456px -72px}
400 396 .icon-plus-sign{background-position:0 -96px}
401 397 .icon-minus-sign{background-position:-24px -96px}
402 398 .icon-remove-sign{background-position:-48px -96px}
403 399 .icon-ok-sign{background-position:-72px -96px}
404 400 .icon-question-sign{background-position:-96px -96px}
405 401 .icon-info-sign{background-position:-120px -96px}
406 402 .icon-screenshot{background-position:-144px -96px}
407 403 .icon-remove-circle{background-position:-168px -96px}
408 404 .icon-ok-circle{background-position:-192px -96px}
409 405 .icon-ban-circle{background-position:-216px -96px}
410 406 .icon-arrow-left{background-position:-240px -96px}
411 407 .icon-arrow-right{background-position:-264px -96px}
412 408 .icon-arrow-up{background-position:-289px -96px}
413 409 .icon-arrow-down{background-position:-312px -96px}
414 410 .icon-share-alt{background-position:-336px -96px}
415 411 .icon-resize-full{background-position:-360px -96px}
416 412 .icon-resize-small{background-position:-384px -96px}
417 413 .icon-plus{background-position:-408px -96px}
418 414 .icon-minus{background-position:-433px -96px}
419 415 .icon-asterisk{background-position:-456px -96px}
420 416 .icon-exclamation-sign{background-position:0 -120px}
421 417 .icon-gift{background-position:-24px -120px}
422 418 .icon-leaf{background-position:-48px -120px}
423 419 .icon-fire{background-position:-72px -120px}
424 420 .icon-eye-open{background-position:-96px -120px}
425 421 .icon-eye-close{background-position:-120px -120px}
426 422 .icon-warning-sign{background-position:-144px -120px}
427 423 .icon-plane{background-position:-168px -120px}
428 424 .icon-calendar{background-position:-192px -120px}
429 425 .icon-random{background-position:-216px -120px;width:16px}
430 426 .icon-comment{background-position:-240px -120px}
431 427 .icon-magnet{background-position:-264px -120px}
432 428 .icon-chevron-up{background-position:-288px -120px}
433 429 .icon-chevron-down{background-position:-313px -119px}
434 430 .icon-retweet{background-position:-336px -120px}
435 431 .icon-shopping-cart{background-position:-360px -120px}
436 432 .icon-folder-close{background-position:-384px -120px;width:16px}
437 433 .icon-folder-open{background-position:-408px -120px;width:16px}
438 434 .icon-resize-vertical{background-position:-432px -119px}
439 435 .icon-resize-horizontal{background-position:-456px -118px}
440 436 .icon-hdd{background-position:0 -144px}
441 437 .icon-bullhorn{background-position:-24px -144px}
442 438 .icon-bell{background-position:-48px -144px}
443 439 .icon-certificate{background-position:-72px -144px}
444 440 .icon-thumbs-up{background-position:-96px -144px}
445 441 .icon-thumbs-down{background-position:-120px -144px}
446 442 .icon-hand-right{background-position:-144px -144px}
447 443 .icon-hand-left{background-position:-168px -144px}
448 444 .icon-hand-up{background-position:-192px -144px}
449 445 .icon-hand-down{background-position:-216px -144px}
450 446 .icon-circle-arrow-right{background-position:-240px -144px}
451 447 .icon-circle-arrow-left{background-position:-264px -144px}
452 448 .icon-circle-arrow-up{background-position:-288px -144px}
453 449 .icon-circle-arrow-down{background-position:-312px -144px}
454 450 .icon-globe{background-position:-336px -144px}
455 451 .icon-wrench{background-position:-360px -144px}
456 452 .icon-tasks{background-position:-384px -144px}
457 453 .icon-filter{background-position:-408px -144px}
458 454 .icon-briefcase{background-position:-432px -144px}
459 455 .icon-fullscreen{background-position:-456px -144px}
460 456 .dropup,.dropdown{position:relative}
461 457 .dropdown-toggle{*margin-bottom:-3px}
462 458 .dropdown-toggle:active,.open .dropdown-toggle{outline:0}
463 459 .caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}
464 460 .dropdown .caret{margin-top:8px;margin-left:2px}
465 461 .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;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}
466 462 .dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}
467 463 .dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}
468 464 .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)}
469 465 .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)}
470 466 .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}
471 467 .dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:default}
472 468 .open{*z-index:1000}.open>.dropdown-menu{display:block}
473 469 .dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}
474 470 .pull-right>.dropdown-menu{right:0;left:auto}
475 471 .dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}
476 472 .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}
477 473 .dropdown-submenu{position:relative}
478 474 .dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;border-radius:0 6px 6px 6px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}
479 475 .dropdown-submenu:hover>.dropdown-menu{display:block}
480 476 .dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;border-radius:5px 5px 5px 0;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}
481 477 .dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}
482 478 .dropdown-submenu:hover>a:after{border-left-color:#fff}
483 479 .dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;border-radius:6px 0 6px 6px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}
484 480 .dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px}
485 481 .typeahead{z-index:1051;margin-top:2px;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
486 482 .well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}
487 483 .well-large{padding:24px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}
488 484 .well-small{padding:9px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
489 485 .fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}
490 486 .collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}
491 487 .close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}
492 488 button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}
493 489 .btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:13px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:-o-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #fff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}
494 490 .btn:active,.btn.active{background-color:#ccc \9}
495 491 .btn:first-child{*margin-left:0}
496 492 .btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}
497 493 .btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}
498 494 .btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)}
499 495 .btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}
500 496 .btn-large{padding:11px 19px;font-size:16.25px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}
501 497 .btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}
502 498 .btn-small{padding:2px 10px;font-size:11.049999999999999px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
503 499 .btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}
504 500 .btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}
505 501 .btn-mini{padding:0 6px;font-size:9.75px;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
506 502 .btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
507 503 .btn-block+.btn-block{margin-top:5px}
508 504 input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}
509 505 .btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}
510 506 .btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}
511 507 .btn-primary:active,.btn-primary.active{background-color:#039 \9}
512 508 .btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}
513 509 .btn-warning:active,.btn-warning.active{background-color:#c67605 \9}
514 510 .btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}
515 511 .btn-danger:active,.btn-danger.active{background-color:#942a25 \9}
516 512 .btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}
517 513 .btn-success:active,.btn-success.active{background-color:#408140 \9}
518 514 .btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}
519 515 .btn-info:active,.btn-info.active{background-color:#24748c \9}
520 516 .btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444, #222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444), to(#222));background-image:-webkit-linear-gradient(top, #444, #222);background-image:-o-linear-gradient(top, #444, #222);background-image:linear-gradient(to bottom, #444, #222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}
521 517 .btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}
522 518 button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}
523 519 button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}
524 520 button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}
525 521 button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}
526 522 .btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}
527 523 .btn-link{border-color:transparent;cursor:pointer;color:#08c;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
528 524 .btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}
529 525 .btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}
530 526 .btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em}.btn-group:first-child{*margin-left:0}
531 527 .btn-group+.btn-group{margin-left:5px}
532 528 .btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}
533 529 .btn-group>.btn{position:relative;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
534 530 .btn-group>.btn+.btn{margin-left:-1px}
535 531 .btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:13px}
536 532 .btn-group>.btn-mini{font-size:9.75px}
537 533 .btn-group>.btn-small{font-size:11.049999999999999px}
538 534 .btn-group>.btn-large{font-size:16.25px}
539 535 .btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}
540 536 .btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}
541 537 .btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}
542 538 .btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}
543 539 .btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}
544 540 .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}
545 541 .btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px}
546 542 .btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px}
547 543 .btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}
548 544 .btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px}
549 545 .btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)}
550 546 .btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}
551 547 .btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}
552 548 .btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}
553 549 .btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}
554 550 .btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}
555 551 .btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}
556 552 .btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}
557 553 .btn .caret{margin-top:8px;margin-left:0}
558 554 .btn-large .caret{margin-top:6px}
559 555 .btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px}
560 556 .btn-mini .caret,.btn-small .caret{margin-top:8px}
561 557 .dropup .btn-large .caret{border-bottom-width:5px}
562 558 .btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}
563 559 .btn-group-vertical{display:inline-block;*display:inline;*zoom:1}
564 560 .btn-group-vertical>.btn{display:block;float:none;max-width:100%;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
565 561 .btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px}
566 562 .btn-group-vertical>.btn:first-child{border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}
567 563 .btn-group-vertical>.btn:last-child{border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}
568 564 .btn-group-vertical>.btn-large:first-child{border-radius:6px 6px 0 0;-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}
569 565 .btn-group-vertical>.btn-large:last-child{border-radius:0 0 6px 6px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}
570 566 .alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
571 567 .alert,.alert h4{color:#c09853}
572 568 .alert h4{margin:0}
573 569 .alert .close{position:relative;top:-2px;right:-21px;line-height:20px}
574 570 .alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847}
575 571 .alert-success h4{color:#468847}
576 572 .alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48}
577 573 .alert-danger h4,.alert-error h4{color:#b94a48}
578 574 .alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad}
579 575 .alert-info h4{color:#3a87ad}
580 576 .alert-block{padding-top:14px;padding-bottom:14px}
581 577 .alert-block>p,.alert-block>ul{margin-bottom:0}
582 578 .alert-block p+p{margin-top:5px}
583 579 .nav{margin-left:0;margin-bottom:20px;list-style:none}
584 580 .nav>li>a{display:block}
585 581 .nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}
586 582 .nav>li>a>img{max-width:none}
587 583 .nav>.pull-right{float:right}
588 584 .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}
589 585 .nav li+.nav-header{margin-top:9px}
590 586 .nav-list{padding-left:15px;padding-right:15px;margin-bottom:0}
591 587 .nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}
592 588 .nav-list>li>a{padding:3px 15px}
593 589 .nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}
594 590 .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}
595 591 .nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}
596 592 .nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0}
597 593 .nav-tabs:after,.nav-pills:after{clear:both}
598 594 .nav-tabs>li,.nav-pills>li{float:left}
599 595 .nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}
600 596 .nav-tabs{border-bottom:1px solid #ddd}
601 597 .nav-tabs>li{margin-bottom:-1px}
602 598 .nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}
603 599 .nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}
604 600 .nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}
605 601 .nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}
606 602 .nav-stacked>li{float:none}
607 603 .nav-stacked>li>a{margin-right:0}
608 604 .nav-tabs.nav-stacked{border-bottom:0}
609 605 .nav-tabs.nav-stacked>li>a{border:1px solid #ddd;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
610 606 .nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}
611 607 .nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}
612 608 .nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2}
613 609 .nav-pills.nav-stacked>li>a{margin-bottom:3px}
614 610 .nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}
615 611 .nav-tabs .dropdown-menu{border-radius:0 0 6px 6px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}
616 612 .nav-pills .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}
617 613 .nav .dropdown-toggle .caret{border-top-color:#08c;border-bottom-color:#08c;margin-top:6px}
618 614 .nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}
619 615 .nav-tabs .dropdown-toggle .caret{margin-top:8px}
620 616 .nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}
621 617 .nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}
622 618 .nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}
623 619 .nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}
624 620 .nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}
625 621 .tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}
626 622 .tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0}
627 623 .tabbable:after{clear:both}
628 624 .tab-content{overflow:auto}
629 625 .tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}
630 626 .tab-content>.tab-pane,.pill-content>.pill-pane{display:none}
631 627 .tab-content>.active,.pill-content>.active{display:block}
632 628 .tabs-below>.nav-tabs{border-top:1px solid #ddd}
633 629 .tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}
634 630 .tabs-below>.nav-tabs>li>a{border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd}
635 631 .tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}
636 632 .tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}
637 633 .tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}
638 634 .tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}
639 635 .tabs-left>.nav-tabs>li>a{margin-right:-1px;border-radius:4px 0 0 4px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}
640 636 .tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}
641 637 .tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}
642 638 .tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}
643 639 .tabs-right>.nav-tabs>li>a{margin-left:-1px;border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}
644 640 .tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}
645 641 .tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}
646 642 .nav>.disabled>a{color:#999}
647 643 .nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default}
648 644 .navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2}
649 645 .navbar-inner{min-height:36px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #fff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #fff, #f2f2f2);background-image:-o-linear-gradient(top, #fff, #f2f2f2);background-image:linear-gradient(to bottom, #fff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065);*zoom:1}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0}
650 646 .navbar-inner:after{clear:both}
651 647 .navbar .container{width:auto}
652 648 .nav-collapse.collapse{height:auto;overflow:visible}
653 649 .navbar .brand{float:left;display:block;padding:8px 20px 8px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}
654 650 .navbar-text{margin-bottom:0;line-height:36px;color:#777}
655 651 .navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}
656 652 .navbar .divider-vertical{height:36px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #fff}
657 653 .navbar .btn,.navbar .btn-group{margin-top:3px}
658 654 .navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}
659 655 .navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0}
660 656 .navbar-form:after{clear:both}
661 657 .navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:3px}
662 658 .navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}
663 659 .navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}
664 660 .navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}
665 661 .navbar-search{position:relative;float:left;margin-top:3px;margin-bottom:0}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}
666 662 .navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
667 663 .navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}
668 664 .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}
669 665 .navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}
670 666 .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
671 667 .navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}
672 668 .navbar-fixed-top{top:0}
673 669 .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1)}
674 670 .navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1)}
675 671 .navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}
676 672 .navbar .nav.pull-right{float:right;margin-right:0}
677 673 .navbar .nav>li{float:left}
678 674 .navbar .nav>li>a{float:none;padding:8px 15px 8px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}
679 675 .navbar .nav .dropdown-toggle .caret{margin-top:8px}
680 676 .navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333;text-decoration:none}
681 677 .navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}
682 678 .navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}
683 679 .navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}
684 680 .navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}
685 681 .btn-navbar .icon-bar+.icon-bar{margin-top:3px}
686 682 .navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:9px}
687 683 .navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px}
688 684 .navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);border-bottom:0;bottom:-7px;top:auto}
689 685 .navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto}
690 686 .navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}
691 687 .navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555}
692 688 .navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}
693 689 .navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}
694 690 .navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px}
695 691 .navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px}
696 692 .navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;border-radius:6px 0 6px 6px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}
697 693 .navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222, #111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222), to(#111));background-image:-webkit-linear-gradient(top, #222, #111);background-image:-o-linear-gradient(top, #222, #111);background-image:linear-gradient(to bottom, #222, #111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525}
698 694 .navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}
699 695 .navbar-inverse .brand{color:#999}
700 696 .navbar-inverse .navbar-text{color:#999}
701 697 .navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#fff}
702 698 .navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}
703 699 .navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}
704 700 .navbar-inverse .divider-vertical{border-left-color:#111;border-right-color:#222}
705 701 .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111;color:#fff}
706 702 .navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}
707 703 .navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}
708 704 .navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}
709 705 .navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}
710 706 .navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}
711 707 .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}
712 708 .navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15);outline:0}
713 709 .navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}
714 710 .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}
715 711 .breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}
716 712 .breadcrumb>.active{color:#999}
717 713 .pagination{margin:20px 0}
718 714 .pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}
719 715 .pagination ul>li{display:inline}
720 716 .pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}
721 717 .pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}
722 718 .pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}
723 719 .pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;background-color:transparent;cursor:default}
724 720 .pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}
725 721 .pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px}
726 722 .pagination-centered{text-align:center}
727 723 .pagination-right{text-align:right}
728 724 .pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:16.25px}
729 725 .pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px}
730 726 .pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px}
731 727 .pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px}
732 728 .pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px}
733 729 .pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.049999999999999px}
734 730 .pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:9.75px}
735 731 .pager{margin:20px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0}
736 732 .pager:after{clear:both}
737 733 .pager li{display:inline}
738 734 .pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}
739 735 .pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}
740 736 .pager .next>a,.pager .next>span{float:right}
741 737 .pager .previous>a,.pager .previous>span{float:left}
742 738 .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:default}
743 739 .modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}
744 740 .modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}
745 741 .modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%}
746 742 .modal.fade.in{top:10%}
747 743 .modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}
748 744 .modal-header h3{margin:0;line-height:30px}
749 745 .modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px}
750 746 .modal-form{margin-bottom:0}
751 747 .modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0}
752 748 .modal-footer:after{clear:both}
753 749 .modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}
754 750 .modal-footer .btn-group .btn+.btn{margin-left:-1px}
755 751 .modal-footer .btn-block+.btn-block{margin-left:0}
756 752 .tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}
757 753 .tooltip.top{margin-top:-3px;padding:5px 0}
758 754 .tooltip.right{margin-left:3px;padding:0 5px}
759 755 .tooltip.bottom{margin-top:3px;padding:5px 0}
760 756 .tooltip.left{margin-left:-3px;padding:0 5px}
761 757 .tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
762 758 .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}
763 759 .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}
764 760 .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}
765 761 .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}
766 762 .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}
767 763 .popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}
768 764 .popover.right{margin-left:10px}
769 765 .popover.bottom{margin-top:10px}
770 766 .popover.left{margin-left:-10px}
771 767 .popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}
772 768 .popover-content{padding:9px 14px}
773 769 .popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}
774 770 .popover .arrow{border-width:11px}
775 771 .popover .arrow:after{border-width:10px;content:""}
776 772 .popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}
777 773 .popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}
778 774 .popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}
779 775 .popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}
780 776 .thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0}
781 777 .thumbnails:after{clear:both}
782 778 .row-fluid .thumbnails{margin-left:0}
783 779 .thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}
784 780 .thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}
785 781 a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}
786 782 .thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto}
787 783 .thumbnail .caption{padding:9px;color:#555}
788 784 .media,.media-body{overflow:hidden;*overflow:visible;zoom:1}
789 785 .media,.media .media{margin-top:15px}
790 786 .media:first-child{margin-top:0}
791 787 .media-object{display:block}
792 788 .media-heading{margin:0 0 5px}
793 789 .media>.pull-left{margin-right:10px}
794 790 .media>.pull-right{margin-left:10px}
795 791 .media-list{margin-left:0;list-style:none}
796 792 .label,.badge{display:inline-block;padding:2px 4px;font-size:10.998px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#999}
797 793 .label{border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
798 794 .badge{padding-left:9px;padding-right:9px;border-radius:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}
799 795 .label:empty,.badge:empty{display:none}
800 796 a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}
801 797 .label-important,.badge-important{background-color:#b94a48}
802 798 .label-important[href],.badge-important[href]{background-color:#953b39}
803 799 .label-warning,.badge-warning{background-color:#f89406}
804 800 .label-warning[href],.badge-warning[href]{background-color:#c67605}
805 801 .label-success,.badge-success{background-color:#468847}
806 802 .label-success[href],.badge-success[href]{background-color:#356635}
807 803 .label-info,.badge-info{background-color:#3a87ad}
808 804 .label-info[href],.badge-info[href]{background-color:#2d6987}
809 805 .label-inverse,.badge-inverse{background-color:#333}
810 806 .label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}
811 807 .btn .label,.btn .badge{position:relative;top:-1px}
812 808 .btn-mini .label,.btn-mini .badge{top:0}
813 809 @-webkit-keyframes progress-bar-stripes{from{background-position:40px 0} to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0} to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0} to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0} to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0} to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
814 810 .progress .bar{width:0;height:100%;color:#fff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}
815 811 .progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15)}
816 812 .progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}
817 813 .progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}
818 814 .progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0)}
819 815 .progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}
820 816 .progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0)}
821 817 .progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}
822 818 .progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0)}
823 819 .progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}
824 820 .progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0)}
825 821 .progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,0.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,0.15)), color-stop(.75, rgba(255,255,255,0.15)), color-stop(.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}
826 822 .accordion{margin-bottom:20px}
827 823 .accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
828 824 .accordion-heading{border-bottom:0}
829 825 .accordion-heading .accordion-toggle{display:block;padding:8px 15px}
830 826 .accordion-toggle{cursor:pointer}
831 827 .accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}
832 828 .carousel{position:relative;margin-bottom:20px;line-height:1}
833 829 .carousel-inner{overflow:hidden;width:100%;position:relative}
834 830 .carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}
835 831 .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}
836 832 .carousel-inner>.active{left:0}
837 833 .carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}
838 834 .carousel-inner>.next{left:100%}
839 835 .carousel-inner>.prev{left:-100%}
840 836 .carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}
841 837 .carousel-inner>.active.left{left:-100%}
842 838 .carousel-inner>.active.right{left:100%}
843 839 .carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px}
844 840 .carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}
845 841 .carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}
846 842 .carousel-indicators .active{background-color:#fff}
847 843 .carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}
848 844 .carousel-caption h4,.carousel-caption p{color:#fff;line-height:20px}
849 845 .carousel-caption h4{margin:0 0 5px}
850 846 .carousel-caption p{margin-bottom:0}
851 847 .hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px}
852 848 .hero-unit li{line-height:30px}
853 849 .pull-right{float:right}
854 850 .pull-left{float:left}
855 851 .hide{display:none}
856 852 .show{display:block}
857 853 .invisible{visibility:hidden}
858 854 .affix{position:fixed}
855 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
856 .clearfix:after{clear:both}
857 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
858 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
859 859 @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}
860 860 .visible-phone{display:none !important}
861 861 .visible-tablet{display:none !important}
862 862 .hidden-desktop{display:none !important}
863 863 .visible-desktop{display:inherit !important}
864 864 @media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important} .visible-desktop{display:none !important} .visible-tablet{display:inherit !important} .hidden-tablet{display:none !important}}@media (max-width:767px){.hidden-desktop{display:inherit !important} .visible-desktop{display:none !important} .visible-phone{display:inherit !important} .hidden-phone{display:none !important}}.visible-print{display:none !important}
865 865 @media print{.visible-print{display:inherit !important} .hidden-print{display:none !important}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0} .row:after{clear:both} [class*="span"]{float:left;min-height:1px;margin-left:30px} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px} .span12{width:1170px} .span11{width:1070px} .span10{width:970px} .span9{width:870px} .span8{width:770px} .span7{width:670px} .span6{width:570px} .span5{width:470px} .span4{width:370px} .span3{width:270px} .span2{width:170px} .span1{width:70px} .offset12{margin-left:1230px} .offset11{margin-left:1130px} .offset10{margin-left:1030px} .offset9{margin-left:930px} .offset8{margin-left:830px} .offset7{margin-left:730px} .offset6{margin-left:630px} .offset5{margin-left:530px} .offset4{margin-left:430px} .offset3{margin-left:330px} .offset2{margin-left:230px} .offset1{margin-left:130px} .row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0} .row-fluid:after{clear:both} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%} .row-fluid [class*="span"]:first-child{margin-left:0} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%} .row-fluid .span12{width:100%;*width:99.94680851063829%} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%} input,textarea,.uneditable-input{margin-left:0} .controls-row [class*="span"]+[class*="span"]{margin-left:30px} input.span12,textarea.span12,.uneditable-input.span12{width:1156px} input.span11,textarea.span11,.uneditable-input.span11{width:1056px} input.span10,textarea.span10,.uneditable-input.span10{width:956px} input.span9,textarea.span9,.uneditable-input.span9{width:856px} input.span8,textarea.span8,.uneditable-input.span8{width:756px} input.span7,textarea.span7,.uneditable-input.span7{width:656px} input.span6,textarea.span6,.uneditable-input.span6{width:556px} input.span5,textarea.span5,.uneditable-input.span5{width:456px} input.span4,textarea.span4,.uneditable-input.span4{width:356px} input.span3,textarea.span3,.uneditable-input.span3{width:256px} input.span2,textarea.span2,.uneditable-input.span2{width:156px} input.span1,textarea.span1,.uneditable-input.span1{width:56px} .thumbnails{margin-left:-30px} .thumbnails>li{margin-left:30px} .row-fluid .thumbnails{margin-left:0}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0} .row:after{clear:both} [class*="span"]{float:left;min-height:1px;margin-left:20px} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px} .span12{width:724px} .span11{width:662px} .span10{width:600px} .span9{width:538px} .span8{width:476px} .span7{width:414px} .span6{width:352px} .span5{width:290px} .span4{width:228px} .span3{width:166px} .span2{width:104px} .span1{width:42px} .offset12{margin-left:764px} .offset11{margin-left:702px} .offset10{margin-left:640px} .offset9{margin-left:578px} .offset8{margin-left:516px} .offset7{margin-left:454px} .offset6{margin-left:392px} .offset5{margin-left:330px} .offset4{margin-left:268px} .offset3{margin-left:206px} .offset2{margin-left:144px} .offset1{margin-left:82px} .row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0} .row-fluid:after{clear:both} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%} .row-fluid [class*="span"]:first-child{margin-left:0} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%} .row-fluid .span12{width:100%;*width:99.94680851063829%} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%} input,textarea,.uneditable-input{margin-left:0} .controls-row [class*="span"]+[class*="span"]{margin-left:20px} input.span12,textarea.span12,.uneditable-input.span12{width:710px} input.span11,textarea.span11,.uneditable-input.span11{width:648px} input.span10,textarea.span10,.uneditable-input.span10{width:586px} input.span9,textarea.span9,.uneditable-input.span9{width:524px} input.span8,textarea.span8,.uneditable-input.span8{width:462px} input.span7,textarea.span7,.uneditable-input.span7{width:400px} input.span6,textarea.span6,.uneditable-input.span6{width:338px} input.span5,textarea.span5,.uneditable-input.span5{width:276px} input.span4,textarea.span4,.uneditable-input.span4{width:214px} input.span3,textarea.span3,.uneditable-input.span3{width:152px} input.span2,textarea.span2,.uneditable-input.span2{width:90px} input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media (max-width:767px){body{padding-left:20px;padding-right:20px} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px} .container-fluid{padding:0} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left} .dl-horizontal dd{margin-left:0} .container{width:auto} .row-fluid{width:100%} .row,.thumbnails{margin-left:0} .thumbnails>li{float:none;margin-left:0} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .row-fluid [class*="offset"]:first-child{margin-left:0} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto} .controls-row [class*="span"]+[class*="span"]{margin-left:0} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0}.modal.fade{top:-100px} .modal.fade.in{top:20px}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0)} .page-header h1 small{display:block;line-height:20px} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left} .form-horizontal .controls{margin-left:0} .form-horizontal .control-list{padding-top:0} .form-horizontal .form-actions{padding-left:10px;padding-right:10px} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px} .media-object{margin-right:0;margin-left:0} .modal{top:10px;left:10px;right:10px} .modal-header .close{padding:10px;margin:-10px} .carousel-caption{position:static}}@media (max-width:979px){body{padding-top:0} .navbar-fixed-top,.navbar-fixed-bottom{position:static} .navbar-fixed-top{margin-bottom:20px} .navbar-fixed-bottom{margin-top:20px} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px} .navbar .container{width:auto;padding:0} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px} .nav-collapse{clear:both} .nav-collapse .nav{float:none;margin:0 0 10px} .nav-collapse .nav>li{float:none} .nav-collapse .nav>li>a{margin-bottom:2px} .nav-collapse .nav>.divider-vertical{display:none} .nav-collapse .nav .nav-header{color:#777;text-shadow:none} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px} .nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111} .nav-collapse.in .btn-group{margin-top:5px;padding:0} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none} .nav-collapse .open>.dropdown-menu{display:block} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none} .nav-collapse .dropdown-menu .divider{display:none} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1)} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0} .navbar .btn-navbar{display:block} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px}}@media (min-width:979px + 1){.nav-collapse.collapse{height:auto !important;overflow:visible !important}}@font-face{font-family:'FontAwesome';src:url('../components/font-awesome/font/fontawesome-webfont.eot?v=3.2.1');src:url('../components/font-awesome/font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'),url('../components/font-awesome/font/fontawesome-webfont.woff?v=3.2.1') format('woff'),url('../components/font-awesome/font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'),url('../components/font-awesome/font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg');font-weight:normal;font-style:normal}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em}
866 866 [class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}
867 867 .icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}
868 868 a [class^="icon-"],a [class*=" icon-"]{display:inline}
869 869 [class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:.2857142857142857em}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em}
870 870 .icons-ul{margin-left:2.142857142857143em;list-style-type:none}.icons-ul>li{position:relative}
871 871 .icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit}
872 872 [class^="icon-"].hide,[class*=" icon-"].hide{display:none}
873 873 .icon-muted{color:#eee}
874 874 .icon-light{color:#fff}
875 875 .icon-dark{color:#333}
876 876 .icon-border{border:solid 1px #eee;padding:.2em .25em .15em;border-radius:3px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
877 877 .icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
878 878 .icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}
879 879 .icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}
880 880 .icon-5x{font-size:5em}.icon-5x.icon-border{border-width:5px;border-radius:7px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}
881 881 .pull-right{float:right}
882 882 .pull-left{float:left}
883 883 [class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}
884 884 [class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}
885 885 [class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0}
886 886 .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}
887 887 .btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}
888 888 .btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}
889 889 .nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em}
890 890 .btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}
891 891 .btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}
892 892 .btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}
893 893 .btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}
894 894 .btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}
895 895 .btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}
896 896 .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit}
897 897 .icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em}
898 898 .icon-stack .icon-stack-base{font-size:2em;*line-height:1em}
899 899 .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}
900 900 a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none}
901 901 @-moz-keyframes spin{0%{-moz-transform:rotate(0deg)} 100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)} 100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)} 100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)} 100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1)}
902 902 .icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2)}
903 903 .icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3)}
904 904 .icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}
905 905 .icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}
906 906 a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block}
907 907 .icon-glass:before{content:"\f000"}
908 908 .icon-music:before{content:"\f001"}
909 909 .icon-search:before{content:"\f002"}
910 910 .icon-envelope-alt:before{content:"\f003"}
911 911 .icon-heart:before{content:"\f004"}
912 912 .icon-star:before{content:"\f005"}
913 913 .icon-star-empty:before{content:"\f006"}
914 914 .icon-user:before{content:"\f007"}
915 915 .icon-film:before{content:"\f008"}
916 916 .icon-th-large:before{content:"\f009"}
917 917 .icon-th:before{content:"\f00a"}
918 918 .icon-th-list:before{content:"\f00b"}
919 919 .icon-ok:before{content:"\f00c"}
920 920 .icon-remove:before{content:"\f00d"}
921 921 .icon-zoom-in:before{content:"\f00e"}
922 922 .icon-zoom-out:before{content:"\f010"}
923 923 .icon-power-off:before,.icon-off:before{content:"\f011"}
924 924 .icon-signal:before{content:"\f012"}
925 925 .icon-gear:before,.icon-cog:before{content:"\f013"}
926 926 .icon-trash:before{content:"\f014"}
927 927 .icon-home:before{content:"\f015"}
928 928 .icon-file-alt:before{content:"\f016"}
929 929 .icon-time:before{content:"\f017"}
930 930 .icon-road:before{content:"\f018"}
931 931 .icon-download-alt:before{content:"\f019"}
932 932 .icon-download:before{content:"\f01a"}
933 933 .icon-upload:before{content:"\f01b"}
934 934 .icon-inbox:before{content:"\f01c"}
935 935 .icon-play-circle:before{content:"\f01d"}
936 936 .icon-rotate-right:before,.icon-repeat:before{content:"\f01e"}
937 937 .icon-refresh:before{content:"\f021"}
938 938 .icon-list-alt:before{content:"\f022"}
939 939 .icon-lock:before{content:"\f023"}
940 940 .icon-flag:before{content:"\f024"}
941 941 .icon-headphones:before{content:"\f025"}
942 942 .icon-volume-off:before{content:"\f026"}
943 943 .icon-volume-down:before{content:"\f027"}
944 944 .icon-volume-up:before{content:"\f028"}
945 945 .icon-qrcode:before{content:"\f029"}
946 946 .icon-barcode:before{content:"\f02a"}
947 947 .icon-tag:before{content:"\f02b"}
948 948 .icon-tags:before{content:"\f02c"}
949 949 .icon-book:before{content:"\f02d"}
950 950 .icon-bookmark:before{content:"\f02e"}
951 951 .icon-print:before{content:"\f02f"}
952 952 .icon-camera:before{content:"\f030"}
953 953 .icon-font:before{content:"\f031"}
954 954 .icon-bold:before{content:"\f032"}
955 955 .icon-italic:before{content:"\f033"}
956 956 .icon-text-height:before{content:"\f034"}
957 957 .icon-text-width:before{content:"\f035"}
958 958 .icon-align-left:before{content:"\f036"}
959 959 .icon-align-center:before{content:"\f037"}
960 960 .icon-align-right:before{content:"\f038"}
961 961 .icon-align-justify:before{content:"\f039"}
962 962 .icon-list:before{content:"\f03a"}
963 963 .icon-indent-left:before{content:"\f03b"}
964 964 .icon-indent-right:before{content:"\f03c"}
965 965 .icon-facetime-video:before{content:"\f03d"}
966 966 .icon-picture:before{content:"\f03e"}
967 967 .icon-pencil:before{content:"\f040"}
968 968 .icon-map-marker:before{content:"\f041"}
969 969 .icon-adjust:before{content:"\f042"}
970 970 .icon-tint:before{content:"\f043"}
971 971 .icon-edit:before{content:"\f044"}
972 972 .icon-share:before{content:"\f045"}
973 973 .icon-check:before{content:"\f046"}
974 974 .icon-move:before{content:"\f047"}
975 975 .icon-step-backward:before{content:"\f048"}
976 976 .icon-fast-backward:before{content:"\f049"}
977 977 .icon-backward:before{content:"\f04a"}
978 978 .icon-play:before{content:"\f04b"}
979 979 .icon-pause:before{content:"\f04c"}
980 980 .icon-stop:before{content:"\f04d"}
981 981 .icon-forward:before{content:"\f04e"}
982 982 .icon-fast-forward:before{content:"\f050"}
983 983 .icon-step-forward:before{content:"\f051"}
984 984 .icon-eject:before{content:"\f052"}
985 985 .icon-chevron-left:before{content:"\f053"}
986 986 .icon-chevron-right:before{content:"\f054"}
987 987 .icon-plus-sign:before{content:"\f055"}
988 988 .icon-minus-sign:before{content:"\f056"}
989 989 .icon-remove-sign:before{content:"\f057"}
990 990 .icon-ok-sign:before{content:"\f058"}
991 991 .icon-question-sign:before{content:"\f059"}
992 992 .icon-info-sign:before{content:"\f05a"}
993 993 .icon-screenshot:before{content:"\f05b"}
994 994 .icon-remove-circle:before{content:"\f05c"}
995 995 .icon-ok-circle:before{content:"\f05d"}
996 996 .icon-ban-circle:before{content:"\f05e"}
997 997 .icon-arrow-left:before{content:"\f060"}
998 998 .icon-arrow-right:before{content:"\f061"}
999 999 .icon-arrow-up:before{content:"\f062"}
1000 1000 .icon-arrow-down:before{content:"\f063"}
1001 1001 .icon-mail-forward:before,.icon-share-alt:before{content:"\f064"}
1002 1002 .icon-resize-full:before{content:"\f065"}
1003 1003 .icon-resize-small:before{content:"\f066"}
1004 1004 .icon-plus:before{content:"\f067"}
1005 1005 .icon-minus:before{content:"\f068"}
1006 1006 .icon-asterisk:before{content:"\f069"}
1007 1007 .icon-exclamation-sign:before{content:"\f06a"}
1008 1008 .icon-gift:before{content:"\f06b"}
1009 1009 .icon-leaf:before{content:"\f06c"}
1010 1010 .icon-fire:before{content:"\f06d"}
1011 1011 .icon-eye-open:before{content:"\f06e"}
1012 1012 .icon-eye-close:before{content:"\f070"}
1013 1013 .icon-warning-sign:before{content:"\f071"}
1014 1014 .icon-plane:before{content:"\f072"}
1015 1015 .icon-calendar:before{content:"\f073"}
1016 1016 .icon-random:before{content:"\f074"}
1017 1017 .icon-comment:before{content:"\f075"}
1018 1018 .icon-magnet:before{content:"\f076"}
1019 1019 .icon-chevron-up:before{content:"\f077"}
1020 1020 .icon-chevron-down:before{content:"\f078"}
1021 1021 .icon-retweet:before{content:"\f079"}
1022 1022 .icon-shopping-cart:before{content:"\f07a"}
1023 1023 .icon-folder-close:before{content:"\f07b"}
1024 1024 .icon-folder-open:before{content:"\f07c"}
1025 1025 .icon-resize-vertical:before{content:"\f07d"}
1026 1026 .icon-resize-horizontal:before{content:"\f07e"}
1027 1027 .icon-bar-chart:before{content:"\f080"}
1028 1028 .icon-twitter-sign:before{content:"\f081"}
1029 1029 .icon-facebook-sign:before{content:"\f082"}
1030 1030 .icon-camera-retro:before{content:"\f083"}
1031 1031 .icon-key:before{content:"\f084"}
1032 1032 .icon-gears:before,.icon-cogs:before{content:"\f085"}
1033 1033 .icon-comments:before{content:"\f086"}
1034 1034 .icon-thumbs-up-alt:before{content:"\f087"}
1035 1035 .icon-thumbs-down-alt:before{content:"\f088"}
1036 1036 .icon-star-half:before{content:"\f089"}
1037 1037 .icon-heart-empty:before{content:"\f08a"}
1038 1038 .icon-signout:before{content:"\f08b"}
1039 1039 .icon-linkedin-sign:before{content:"\f08c"}
1040 1040 .icon-pushpin:before{content:"\f08d"}
1041 1041 .icon-external-link:before{content:"\f08e"}
1042 1042 .icon-signin:before{content:"\f090"}
1043 1043 .icon-trophy:before{content:"\f091"}
1044 1044 .icon-github-sign:before{content:"\f092"}
1045 1045 .icon-upload-alt:before{content:"\f093"}
1046 1046 .icon-lemon:before{content:"\f094"}
1047 1047 .icon-phone:before{content:"\f095"}
1048 1048 .icon-unchecked:before,.icon-check-empty:before{content:"\f096"}
1049 1049 .icon-bookmark-empty:before{content:"\f097"}
1050 1050 .icon-phone-sign:before{content:"\f098"}
1051 1051 .icon-twitter:before{content:"\f099"}
1052 1052 .icon-facebook:before{content:"\f09a"}
1053 1053 .icon-github:before{content:"\f09b"}
1054 1054 .icon-unlock:before{content:"\f09c"}
1055 1055 .icon-credit-card:before{content:"\f09d"}
1056 1056 .icon-rss:before{content:"\f09e"}
1057 1057 .icon-hdd:before{content:"\f0a0"}
1058 1058 .icon-bullhorn:before{content:"\f0a1"}
1059 1059 .icon-bell:before{content:"\f0a2"}
1060 1060 .icon-certificate:before{content:"\f0a3"}
1061 1061 .icon-hand-right:before{content:"\f0a4"}
1062 1062 .icon-hand-left:before{content:"\f0a5"}
1063 1063 .icon-hand-up:before{content:"\f0a6"}
1064 1064 .icon-hand-down:before{content:"\f0a7"}
1065 1065 .icon-circle-arrow-left:before{content:"\f0a8"}
1066 1066 .icon-circle-arrow-right:before{content:"\f0a9"}
1067 1067 .icon-circle-arrow-up:before{content:"\f0aa"}
1068 1068 .icon-circle-arrow-down:before{content:"\f0ab"}
1069 1069 .icon-globe:before{content:"\f0ac"}
1070 1070 .icon-wrench:before{content:"\f0ad"}
1071 1071 .icon-tasks:before{content:"\f0ae"}
1072 1072 .icon-filter:before{content:"\f0b0"}
1073 1073 .icon-briefcase:before{content:"\f0b1"}
1074 1074 .icon-fullscreen:before{content:"\f0b2"}
1075 1075 .icon-group:before{content:"\f0c0"}
1076 1076 .icon-link:before{content:"\f0c1"}
1077 1077 .icon-cloud:before{content:"\f0c2"}
1078 1078 .icon-beaker:before{content:"\f0c3"}
1079 1079 .icon-cut:before{content:"\f0c4"}
1080 1080 .icon-copy:before{content:"\f0c5"}
1081 1081 .icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6"}
1082 1082 .icon-save:before{content:"\f0c7"}
1083 1083 .icon-sign-blank:before{content:"\f0c8"}
1084 1084 .icon-reorder:before{content:"\f0c9"}
1085 1085 .icon-list-ul:before{content:"\f0ca"}
1086 1086 .icon-list-ol:before{content:"\f0cb"}
1087 1087 .icon-strikethrough:before{content:"\f0cc"}
1088 1088 .icon-underline:before{content:"\f0cd"}
1089 1089 .icon-table:before{content:"\f0ce"}
1090 1090 .icon-magic:before{content:"\f0d0"}
1091 1091 .icon-truck:before{content:"\f0d1"}
1092 1092 .icon-pinterest:before{content:"\f0d2"}
1093 1093 .icon-pinterest-sign:before{content:"\f0d3"}
1094 1094 .icon-google-plus-sign:before{content:"\f0d4"}
1095 1095 .icon-google-plus:before{content:"\f0d5"}
1096 1096 .icon-money:before{content:"\f0d6"}
1097 1097 .icon-caret-down:before{content:"\f0d7"}
1098 1098 .icon-caret-up:before{content:"\f0d8"}
1099 1099 .icon-caret-left:before{content:"\f0d9"}
1100 1100 .icon-caret-right:before{content:"\f0da"}
1101 1101 .icon-columns:before{content:"\f0db"}
1102 1102 .icon-sort:before{content:"\f0dc"}
1103 1103 .icon-sort-down:before{content:"\f0dd"}
1104 1104 .icon-sort-up:before{content:"\f0de"}
1105 1105 .icon-envelope:before{content:"\f0e0"}
1106 1106 .icon-linkedin:before{content:"\f0e1"}
1107 1107 .icon-rotate-left:before,.icon-undo:before{content:"\f0e2"}
1108 1108 .icon-legal:before{content:"\f0e3"}
1109 1109 .icon-dashboard:before{content:"\f0e4"}
1110 1110 .icon-comment-alt:before{content:"\f0e5"}
1111 1111 .icon-comments-alt:before{content:"\f0e6"}
1112 1112 .icon-bolt:before{content:"\f0e7"}
1113 1113 .icon-sitemap:before{content:"\f0e8"}
1114 1114 .icon-umbrella:before{content:"\f0e9"}
1115 1115 .icon-paste:before{content:"\f0ea"}
1116 1116 .icon-lightbulb:before{content:"\f0eb"}
1117 1117 .icon-exchange:before{content:"\f0ec"}
1118 1118 .icon-cloud-download:before{content:"\f0ed"}
1119 1119 .icon-cloud-upload:before{content:"\f0ee"}
1120 1120 .icon-user-md:before{content:"\f0f0"}
1121 1121 .icon-stethoscope:before{content:"\f0f1"}
1122 1122 .icon-suitcase:before{content:"\f0f2"}
1123 1123 .icon-bell-alt:before{content:"\f0f3"}
1124 1124 .icon-coffee:before{content:"\f0f4"}
1125 1125 .icon-food:before{content:"\f0f5"}
1126 1126 .icon-file-text-alt:before{content:"\f0f6"}
1127 1127 .icon-building:before{content:"\f0f7"}
1128 1128 .icon-hospital:before{content:"\f0f8"}
1129 1129 .icon-ambulance:before{content:"\f0f9"}
1130 1130 .icon-medkit:before{content:"\f0fa"}
1131 1131 .icon-fighter-jet:before{content:"\f0fb"}
1132 1132 .icon-beer:before{content:"\f0fc"}
1133 1133 .icon-h-sign:before{content:"\f0fd"}
1134 1134 .icon-plus-sign-alt:before{content:"\f0fe"}
1135 1135 .icon-double-angle-left:before{content:"\f100"}
1136 1136 .icon-double-angle-right:before{content:"\f101"}
1137 1137 .icon-double-angle-up:before{content:"\f102"}
1138 1138 .icon-double-angle-down:before{content:"\f103"}
1139 1139 .icon-angle-left:before{content:"\f104"}
1140 1140 .icon-angle-right:before{content:"\f105"}
1141 1141 .icon-angle-up:before{content:"\f106"}
1142 1142 .icon-angle-down:before{content:"\f107"}
1143 1143 .icon-desktop:before{content:"\f108"}
1144 1144 .icon-laptop:before{content:"\f109"}
1145 1145 .icon-tablet:before{content:"\f10a"}
1146 1146 .icon-mobile-phone:before{content:"\f10b"}
1147 1147 .icon-circle-blank:before{content:"\f10c"}
1148 1148 .icon-quote-left:before{content:"\f10d"}
1149 1149 .icon-quote-right:before{content:"\f10e"}
1150 1150 .icon-spinner:before{content:"\f110"}
1151 1151 .icon-circle:before{content:"\f111"}
1152 1152 .icon-mail-reply:before,.icon-reply:before{content:"\f112"}
1153 1153 .icon-github-alt:before{content:"\f113"}
1154 1154 .icon-folder-close-alt:before{content:"\f114"}
1155 1155 .icon-folder-open-alt:before{content:"\f115"}
1156 1156 .icon-expand-alt:before{content:"\f116"}
1157 1157 .icon-collapse-alt:before{content:"\f117"}
1158 1158 .icon-smile:before{content:"\f118"}
1159 1159 .icon-frown:before{content:"\f119"}
1160 1160 .icon-meh:before{content:"\f11a"}
1161 1161 .icon-gamepad:before{content:"\f11b"}
1162 1162 .icon-keyboard:before{content:"\f11c"}
1163 1163 .icon-flag-alt:before{content:"\f11d"}
1164 1164 .icon-flag-checkered:before{content:"\f11e"}
1165 1165 .icon-terminal:before{content:"\f120"}
1166 1166 .icon-code:before{content:"\f121"}
1167 1167 .icon-reply-all:before{content:"\f122"}
1168 1168 .icon-mail-reply-all:before{content:"\f122"}
1169 1169 .icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123"}
1170 1170 .icon-location-arrow:before{content:"\f124"}
1171 1171 .icon-crop:before{content:"\f125"}
1172 1172 .icon-code-fork:before{content:"\f126"}
1173 1173 .icon-unlink:before{content:"\f127"}
1174 1174 .icon-question:before{content:"\f128"}
1175 1175 .icon-info:before{content:"\f129"}
1176 1176 .icon-exclamation:before{content:"\f12a"}
1177 1177 .icon-superscript:before{content:"\f12b"}
1178 1178 .icon-subscript:before{content:"\f12c"}
1179 1179 .icon-eraser:before{content:"\f12d"}
1180 1180 .icon-puzzle-piece:before{content:"\f12e"}
1181 1181 .icon-microphone:before{content:"\f130"}
1182 1182 .icon-microphone-off:before{content:"\f131"}
1183 1183 .icon-shield:before{content:"\f132"}
1184 1184 .icon-calendar-empty:before{content:"\f133"}
1185 1185 .icon-fire-extinguisher:before{content:"\f134"}
1186 1186 .icon-rocket:before{content:"\f135"}
1187 1187 .icon-maxcdn:before{content:"\f136"}
1188 1188 .icon-chevron-sign-left:before{content:"\f137"}
1189 1189 .icon-chevron-sign-right:before{content:"\f138"}
1190 1190 .icon-chevron-sign-up:before{content:"\f139"}
1191 1191 .icon-chevron-sign-down:before{content:"\f13a"}
1192 1192 .icon-html5:before{content:"\f13b"}
1193 1193 .icon-css3:before{content:"\f13c"}
1194 1194 .icon-anchor:before{content:"\f13d"}
1195 1195 .icon-unlock-alt:before{content:"\f13e"}
1196 1196 .icon-bullseye:before{content:"\f140"}
1197 1197 .icon-ellipsis-horizontal:before{content:"\f141"}
1198 1198 .icon-ellipsis-vertical:before{content:"\f142"}
1199 1199 .icon-rss-sign:before{content:"\f143"}
1200 1200 .icon-play-sign:before{content:"\f144"}
1201 1201 .icon-ticket:before{content:"\f145"}
1202 1202 .icon-minus-sign-alt:before{content:"\f146"}
1203 1203 .icon-check-minus:before{content:"\f147"}
1204 1204 .icon-level-up:before{content:"\f148"}
1205 1205 .icon-level-down:before{content:"\f149"}
1206 1206 .icon-check-sign:before{content:"\f14a"}
1207 1207 .icon-edit-sign:before{content:"\f14b"}
1208 1208 .icon-external-link-sign:before{content:"\f14c"}
1209 1209 .icon-share-sign:before{content:"\f14d"}
1210 1210 .icon-compass:before{content:"\f14e"}
1211 1211 .icon-collapse:before{content:"\f150"}
1212 1212 .icon-collapse-top:before{content:"\f151"}
1213 1213 .icon-expand:before{content:"\f152"}
1214 1214 .icon-euro:before,.icon-eur:before{content:"\f153"}
1215 1215 .icon-gbp:before{content:"\f154"}
1216 1216 .icon-dollar:before,.icon-usd:before{content:"\f155"}
1217 1217 .icon-rupee:before,.icon-inr:before{content:"\f156"}
1218 1218 .icon-yen:before,.icon-jpy:before{content:"\f157"}
1219 1219 .icon-renminbi:before,.icon-cny:before{content:"\f158"}
1220 1220 .icon-won:before,.icon-krw:before{content:"\f159"}
1221 1221 .icon-bitcoin:before,.icon-btc:before{content:"\f15a"}
1222 1222 .icon-file:before{content:"\f15b"}
1223 1223 .icon-file-text:before{content:"\f15c"}
1224 1224 .icon-sort-by-alphabet:before{content:"\f15d"}
1225 1225 .icon-sort-by-alphabet-alt:before{content:"\f15e"}
1226 1226 .icon-sort-by-attributes:before{content:"\f160"}
1227 1227 .icon-sort-by-attributes-alt:before{content:"\f161"}
1228 1228 .icon-sort-by-order:before{content:"\f162"}
1229 1229 .icon-sort-by-order-alt:before{content:"\f163"}
1230 1230 .icon-thumbs-up:before{content:"\f164"}
1231 1231 .icon-thumbs-down:before{content:"\f165"}
1232 1232 .icon-youtube-sign:before{content:"\f166"}
1233 1233 .icon-youtube:before{content:"\f167"}
1234 1234 .icon-xing:before{content:"\f168"}
1235 1235 .icon-xing-sign:before{content:"\f169"}
1236 1236 .icon-youtube-play:before{content:"\f16a"}
1237 1237 .icon-dropbox:before{content:"\f16b"}
1238 1238 .icon-stackexchange:before{content:"\f16c"}
1239 1239 .icon-instagram:before{content:"\f16d"}
1240 1240 .icon-flickr:before{content:"\f16e"}
1241 1241 .icon-adn:before{content:"\f170"}
1242 1242 .icon-bitbucket:before{content:"\f171"}
1243 1243 .icon-bitbucket-sign:before{content:"\f172"}
1244 1244 .icon-tumblr:before{content:"\f173"}
1245 1245 .icon-tumblr-sign:before{content:"\f174"}
1246 1246 .icon-long-arrow-down:before{content:"\f175"}
1247 1247 .icon-long-arrow-up:before{content:"\f176"}
1248 1248 .icon-long-arrow-left:before{content:"\f177"}
1249 1249 .icon-long-arrow-right:before{content:"\f178"}
1250 1250 .icon-apple:before{content:"\f179"}
1251 1251 .icon-windows:before{content:"\f17a"}
1252 1252 .icon-android:before{content:"\f17b"}
1253 1253 .icon-linux:before{content:"\f17c"}
1254 1254 .icon-dribbble:before{content:"\f17d"}
1255 1255 .icon-skype:before{content:"\f17e"}
1256 1256 .icon-foursquare:before{content:"\f180"}
1257 1257 .icon-trello:before{content:"\f181"}
1258 1258 .icon-female:before{content:"\f182"}
1259 1259 .icon-male:before{content:"\f183"}
1260 1260 .icon-gittip:before{content:"\f184"}
1261 1261 .icon-sun:before{content:"\f185"}
1262 1262 .icon-moon:before{content:"\f186"}
1263 1263 .icon-archive:before{content:"\f187"}
1264 1264 .icon-bug:before{content:"\f188"}
1265 1265 .icon-vk:before{content:"\f189"}
1266 1266 .icon-weibo:before{content:"\f18a"}
1267 1267 .icon-renren:before{content:"\f18b"}
1268 1268 .border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1269 1269 .corner-all{border-radius:4px}
1270 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
1271 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1272 .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%}
1273 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1274 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
1275 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0}
1276 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1277 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1278 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
1270 .hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
1271 .hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1272 .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%;display:flex;flex-direction:column;align-items:stretch}
1273 .vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1274 .reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse}
1275 .box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:auto}
1276 .box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1277 .box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1278 .box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
1279 1279 .box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}
1280 1280 .box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}
1281 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start}
1282 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end}
1283 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center}
1284 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start}
1285 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end}
1286 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center}
1281 .start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start}
1282 .end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end}
1283 .center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center}
1284 .align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-content:flex-start}
1285 .align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-content:flex-end}
1286 .align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-content:center}
1287 1287 div.error{margin:2em;text-align:center}
1288 1288 div.error>h1{font-size:500%;line-height:normal}
1289 1289 div.error>p{font-size:200%;line-height:normal}
1290 1290 div.traceback-wrapper{text-align:left;max-width:800px;margin:auto}
1291 1291 body{background-color:#fff;position:absolute;left:0;right:0;top:0;bottom:0;overflow:visible}
1292 1292 div#header{display:none}
1293 1293 #ipython_notebook{padding-left:16px}
1294 1294 #noscript{width:auto;padding-top:16px;padding-bottom:16px;text-align:center;font-size:22px;color:#f00;font-weight:bold}
1295 1295 #ipython_notebook img{font-family:Verdana,"Helvetica Neue",Arial,Helvetica,Geneva,sans-serif;height:24px;text-decoration:none;color:#000}
1296 1296 #site{width:100%;display:none}
1297 1297 .ui-button .ui-button-text{padding:.2em .8em;font-size:77%}
1298 1298 input.ui-button{padding:.3em .9em}
1299 1299 .navbar span{margin-top:3px}
1300 1300 span#login_widget{float:right}
1301 1301 .nav-header{text-transform:none}
1302 1302 .navbar-nobg{background-color:transparent;background-image:none}
1303 1303 #header>span{margin-top:10px}
1304 1304 .modal-body{max-height:500px}
1305 1305 .center-nav{display:inline-block;margin-bottom:-4px}
1306 1306 .alternate_upload{background-color:none;display:inline}
1307 1307 .alternate_upload.form{padding:0;margin:0}
1308 1308 .alternate_upload input.fileinput{background-color:#f00;position:relative;opacity:0;z-index:2;width:295px;margin-left:163px;cursor:pointer;height:26px}
1309 1309 ul#tabs{margin-bottom:4px}
1310 1310 ul#tabs a{padding-top:4px;padding-bottom:4px}
1311 1311 ul.breadcrumb a:focus,ul.breadcrumb a:hover{text-decoration:none}
1312 1312 ul.breadcrumb i.icon-home{font-size:16px;margin-right:4px}
1313 1313 ul.breadcrumb span{color:#5e5e5e}
1314 1314 .list_toolbar{padding:4px 0 4px 0}
1315 1315 .list_toolbar [class*="span"]{min-height:26px}
1316 1316 .list_header{font-weight:bold}
1317 1317 .list_container{margin-top:4px;margin-bottom:20px;border:1px solid #ababab;border-radius:4px}
1318 1318 .list_container>div{border-bottom:1px solid #ababab}.list_container>div:hover .list-item{background-color:#f00}
1319 1319 .list_container>div:last-child{border:none}
1320 1320 .list_item:hover .list_item{background-color:#ddd}
1321 1321 .list_item a{text-decoration:none}
1322 1322 .list_header>div,.list_item>div{padding-top:4px;padding-bottom:4px;padding-left:7px;padding-right:7px;height:22px;line-height:22px}
1323 1323 .item_name{line-height:22px;height:26px}
1324 1324 .item_icon{font-size:14px;color:#5e5e5e;margin-right:7px}
1325 1325 .item_buttons{line-height:1em}
1326 1326 .toolbar_info{height:26px;line-height:26px}
1327 1327 input.nbname_input,input.engine_num_input{padding-top:3px;padding-bottom:3px;height:14px;line-height:14px;margin:0}
1328 1328 input.engine_num_input{width:60px}
1329 1329 .highlight_text{color:#00f}
1330 1330 #project_name>.breadcrumb{padding:0;margin-bottom:0;background-color:transparent;font-weight:bold}
1331 1331 .ansibold{font-weight:bold}
1332 1332 .ansiblack{color:#000}
1333 1333 .ansired{color:#8b0000}
1334 1334 .ansigreen{color:#006400}
1335 1335 .ansiyellow{color:#a52a2a}
1336 1336 .ansiblue{color:#00008b}
1337 1337 .ansipurple{color:#9400d3}
1338 1338 .ansicyan{color:#4682b4}
1339 1339 .ansigray{color:#808080}
1340 1340 .ansibgblack{background-color:#000}
1341 1341 .ansibgred{background-color:#f00}
1342 1342 .ansibggreen{background-color:#008000}
1343 1343 .ansibgyellow{background-color:#ff0}
1344 1344 .ansibgblue{background-color:#00f}
1345 1345 .ansibgpurple{background-color:#f0f}
1346 1346 .ansibgcyan{background-color:#0ff}
1347 1347 .ansibggray{background-color:#808080}
1348 div.cell{border:1px solid transparent;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%}div.cell.selected{border-radius:4px;border:thin #ababab solid}
1348 div.cell{border:1px solid transparent;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%;display:flex;flex-direction:column;align-items:stretch}div.cell.selected{border-radius:4px;border:thin #ababab solid}
1349 1349 div.cell.edit_mode{border-radius:4px;border:thin #008000 solid}
1350 1350 div.cell{width:100%;padding:5px 5px 5px 0;margin:0;outline:none}
1351 1351 div.prompt{min-width:11ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.231em}
1352 div.inner_cell{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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;overflow:auto}
1352 div.inner_cell{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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1353 1353 div.prompt:empty{padding-top:0;padding-bottom:0}
1354 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
1354 div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
1355 1355 div.input_area{border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1356 1356 div.input_prompt{color:#000080;border-top:1px solid transparent}
1357 1357 .CodeMirror{line-height:1.231em;height:auto;background:none;}
1358 1358 .CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}
1359 @-moz-document url-prefix(){.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
1359 @-moz-document {.CodeMirror-scroll{overflow-x:hidden}}.CodeMirror-lines{padding:.4em}
1360 1360 .CodeMirror-linenumber{padding:0 8px 0 4px}
1361 1361 .CodeMirror-gutters{border-bottom-left-radius:4px;border-top-left-radius:4px}
1362 1362 .CodeMirror pre{padding:0;border:0;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}
1363 1363 pre code{display:block;padding:.5em}
1364 1364 .highlight-base,pre code,pre .subst,pre .tag .title,pre .lisp .title,pre .clojure .built_in,pre .nginx .title{color:#000}
1365 1365 .highlight-string,pre .string,pre .constant,pre .parent,pre .tag .value,pre .rules .value,pre .rules .value .number,pre .preprocessor,pre .ruby .symbol,pre .ruby .symbol .string,pre .aggregate,pre .template_tag,pre .django .variable,pre .smalltalk .class,pre .addition,pre .flow,pre .stream,pre .bash .variable,pre .apache .tag,pre .apache .cbracket,pre .tex .command,pre .tex .special,pre .erlang_repl .function_or_atom,pre .markdown .header{color:#ba2121}
1366 1366 .highlight-comment,pre .comment,pre .annotation,pre .template_comment,pre .diff .header,pre .chunk,pre .markdown .blockquote{color:#408080;font-style:italic}
1367 1367 .highlight-number,pre .number,pre .date,pre .regexp,pre .literal,pre .smalltalk .symbol,pre .smalltalk .char,pre .go .constant,pre .change,pre .markdown .bullet,pre .markdown .link_url{color:#080}
1368 1368 pre .label,pre .javadoc,pre .ruby .string,pre .decorator,pre .filter .argument,pre .localvars,pre .array,pre .attr_selector,pre .important,pre .pseudo,pre .pi,pre .doctype,pre .deletion,pre .envvar,pre .shebang,pre .apache .sqbracket,pre .nginx .built_in,pre .tex .formula,pre .erlang_repl .reserved,pre .prompt,pre .markdown .link_label,pre .vhdl .attribute,pre .clojure .attribute,pre .coffeescript .property{color:#88f}
1369 1369 .highlight-keyword,pre .keyword,pre .id,pre .phpdoc,pre .aggregate,pre .css .tag,pre .javadoctag,pre .phpdoc,pre .yardoctag,pre .smalltalk .class,pre .winutils,pre .bash .variable,pre .apache .tag,pre .go .typename,pre .tex .command,pre .markdown .strong,pre .request,pre .status{color:#008000;font-weight:bold}
1370 1370 .highlight-builtin,pre .built_in{color:#008000}
1371 1371 pre .markdown .emphasis{font-style:italic}
1372 1372 pre .nginx .built_in{font-weight:normal}
1373 1373 pre .coffeescript .javascript,pre .javascript .xml,pre .tex .formula,pre .xml .javascript,pre .xml .vbscript,pre .xml .css,pre .xml .cdata{opacity:.5}
1374 1374 .cm-s-ipython span.cm-variable{color:#000}
1375 1375 .cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold}
1376 1376 .cm-s-ipython span.cm-number{color:#080}
1377 1377 .cm-s-ipython span.cm-comment{color:#408080;font-style:italic}
1378 1378 .cm-s-ipython span.cm-string{color:#ba2121}
1379 1379 .cm-s-ipython span.cm-builtin{color:#008000}
1380 1380 .cm-s-ipython span.cm-error{color:#f00}
1381 1381 .cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}
1382 1382 .cm-s-ipython span.cm-meta{color:#a2f}
1383 1383 .cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}
1384 div.output_wrapper{position:relative;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%}
1384 div.output_wrapper{position:relative;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%;display:flex;flex-direction:column;align-items:stretch}
1385 1385 div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:4px;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);-moz-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);box-shadow:inset 0 2px 8px rgba(0,0,0,0.8)}
1386 div.output_collapsed{margin:0;padding:0;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%}
1386 div.output_collapsed{margin:0;padding:0;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%;display:flex;flex-direction:column;align-items:stretch}
1387 1387 div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:4px}
1388 1388 div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;-moz-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)}
1389 1389 div.output_prompt{color:#8b0000}
1390 div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}div.output_area .MathJax_Display{text-align:left !important}
1390 div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important}
1391 1391 div.output_area .rendered_html table{margin-left:0;margin-right:0}
1392 1392 div.output_area .rendered_html img{margin-left:0;margin-right:0}
1393 .output{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%}
1393 .output{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%;display:flex;flex-direction:column;align-items:stretch}
1394 1394 div.output_area pre{font-family:monospace;margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;color:#000;background-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;line-height:inherit}
1395 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}
1395 div.output_subarea{padding:.4em .4em 0 .4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}
1396 1396 div.output_text{text-align:left;color:#000;font-family:monospace;line-height:1.231em}
1397 1397 div.output_stderr{background:#fdd;}
1398 1398 div.output_latex{text-align:left}
1399 1399 div.output_javascript:empty{padding:0}
1400 1400 .js-error{color:#8b0000}
1401 1401 div.raw_input{padding-top:0;padding-bottom:0;height:1em;line-height:1em;font-family:monospace}
1402 1402 span.input_prompt{font-family:inherit}
1403 1403 input.raw_input{font-family:inherit;font-size:inherit;color:inherit;width:auto;margin:-2px 0 0 1px;padding-left:1px;padding-top:2px;height:1em}
1404 1404 p.p-space{margin-bottom:10px}
1405 1405 .rendered_html{color:#000;}.rendered_html em{font-style:italic}
1406 1406 .rendered_html strong{font-weight:bold}
1407 1407 .rendered_html u{text-decoration:underline}
1408 1408 .rendered_html :link{text-decoration:underline}
1409 1409 .rendered_html :visited{text-decoration:underline}
1410 1410 .rendered_html h1{font-size:185.7%;margin:1.08em 0 0 0;font-weight:bold;line-height:1}
1411 1411 .rendered_html h2{font-size:157.1%;margin:1.27em 0 0 0;font-weight:bold;line-height:1}
1412 1412 .rendered_html h3{font-size:128.6%;margin:1.55em 0 0 0;font-weight:bold;line-height:1}
1413 1413 .rendered_html h4{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1}
1414 1414 .rendered_html h5{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic}
1415 1415 .rendered_html h6{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1;font-style:italic}
1416 1416 .rendered_html h1:first-child{margin-top:.538em}
1417 1417 .rendered_html h2:first-child{margin-top:.636em}
1418 1418 .rendered_html h3:first-child{margin-top:.777em}
1419 1419 .rendered_html h4:first-child{margin-top:1em}
1420 1420 .rendered_html h5:first-child{margin-top:1em}
1421 1421 .rendered_html h6:first-child{margin-top:1em}
1422 1422 .rendered_html ul{list-style:disc;margin:0 2em}
1423 1423 .rendered_html ul ul{list-style:square;margin:0 2em}
1424 1424 .rendered_html ul ul ul{list-style:circle;margin:0 2em}
1425 1425 .rendered_html ol{list-style:decimal;margin:0 2em}
1426 1426 .rendered_html ol ol{list-style:upper-alpha;margin:0 2em}
1427 1427 .rendered_html ol ol ol{list-style:lower-alpha;margin:0 2em}
1428 1428 .rendered_html ol ol ol ol{list-style:lower-roman;margin:0 2em}
1429 1429 .rendered_html ol ol ol ol ol{list-style:decimal;margin:0 2em}
1430 1430 .rendered_html *+ul{margin-top:1em}
1431 1431 .rendered_html *+ol{margin-top:1em}
1432 1432 .rendered_html hr{color:#000;background-color:#000}
1433 1433 .rendered_html pre{margin:1em 2em}
1434 1434 .rendered_html pre,.rendered_html code{border:0;background-color:#fff;color:#000;font-size:100%;padding:0}
1435 1435 .rendered_html blockquote{margin:1em 2em}
1436 1436 .rendered_html table{margin-left:auto;margin-right:auto;border:1px solid #000;border-collapse:collapse}
1437 1437 .rendered_html tr,.rendered_html th,.rendered_html td{border:1px solid #000;border-collapse:collapse;margin:1em 2em}
1438 1438 .rendered_html td,.rendered_html th{text-align:left;vertical-align:middle;padding:4px}
1439 1439 .rendered_html th{font-weight:bold}
1440 1440 .rendered_html *+table{margin-top:1em}
1441 1441 .rendered_html p{text-align:justify}
1442 1442 .rendered_html *+p{margin-top:1em}
1443 1443 .rendered_html img{display:block;margin-left:auto;margin-right:auto}
1444 1444 .rendered_html *+img{margin-top:1em}
1445 div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
1445 div.text_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
1446 1446 div.text_cell_input{color:#000;border:1px solid #cfcfcf;border-radius:4px;background:#f7f7f7}
1447 1447 div.text_cell_render{outline:none;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000}
1448 1448 a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}
1449 1449 h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible}
1450 1450 div.cell.text_cell.rendered{padding:0}
1451 .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2}
1451 .widget-area{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-area .widget-subarea{padding:.44em .4em .4em 1px;margin-left:6px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}
1452 1452 .widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
1453 1453 .widget-vlabel{padding-bottom:5px;text-align:center;vertical-align:text-bottom}
1454 1454 .widget-hreadout{padding-left:8px;padding-top:3px;text-align:left;vertical-align:text-top}
1455 1455 .widget-vreadout{padding-top:5px;text-align:center;vertical-align:text-top}
1456 1456 .slide-track{border:1px solid #ccc;background:#fff;border-radius:4px;}
1457 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
1458 .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
1457 .widget-hslider{padding-left:8px;padding-right:5px;overflow:visible;width:348px;height:5px;max-height:5px;margin-top:11px;border:1px solid #ccc;background:#fff;border-radius:4px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.widget-hslider .ui-slider{border:0 !important;background:none !important;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-hslider .ui-slider .ui-slider-handle{width:14px !important;height:28px !important;margin-top:-8px !important}
1458 .widget-vslider{padding-bottom:8px;overflow:visible;width:5px;max-width:5px;height:250px;margin-left:12px;border:1px solid #ccc;background:#fff;border-radius:4px;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%;display:flex;flex-direction:column;align-items:stretch}.widget-vslider .ui-slider{border:0 !important;background:none !important;margin-left:-4px;margin-top:5px;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%;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.widget-vslider .ui-slider .ui-slider-handle{width:28px !important;height:14px !important;margin-left:-9px}
1459 1459 .widget-text{width:350px;margin-bottom:0}
1460 1460 .widget-listbox{width:364px;margin-bottom:0}
1461 1461 .widget-numeric-text{width:150px}
1462 1462 .widget-progress{width:363px}.widget-progress .bar{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}
1463 1463 .widget-combo-btn{min-width:138px;}
1464 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1465 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch}
1466 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;height:30px}
1467 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%}
1468 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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:30px}
1464 .widget-box{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1465 .widget-hbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}
1466 .widget-hbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;height:30px}
1467 .widget-vbox{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch}
1468 .widget-vbox-single{margin:5px;-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;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%;display:flex;flex-direction:column;align-items:stretch;width:30px}
1469 1469 .widget-modal{overflow:hidden;position:absolute !important;top:0;left:0;margin-left:0 !important}
1470 1470 .widget-modal-body{max-height:none !important}
1471 1471 .widget-container{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1472 1472 .docked-widget-modal{overflow:hidden;position:relative !important;top:0 !important;left:0 !important;margin-left:0 !important}
1473 1473 body{background-color:#fff}
1474 1474 body.notebook_app{overflow:hidden}
1475 1475 span#notebook_name{height:1em;line-height:1em;padding:3px;border:none;font-size:146.5%}
1476 1476 div#notebook_panel{margin:0 0 0 0;padding:0;-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}
1477 1477 div#notebook{overflow-y:scroll;overflow-x:auto;width:100%;padding:1em 0 1em 0;margin:0;border-top:1px solid #ababab;outline:none;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}
1478 1478 div.ui-widget-content{border:1px solid #ababab;outline:none}
1479 1479 pre.dialog{background-color:#f7f7f7;border:1px solid #ddd;border-radius:4px;padding:.4em;padding-left:2em}
1480 1480 p.dialog{padding:.2em}
1481 1481 pre,code,kbd,samp{white-space:pre-wrap}
1482 1482 #fonttest{font-family:monospace}
1483 1483 p{margin-bottom:0}
1484 1484 .end_space{height:200px}
1485 .celltoolbar{border:thin solid #cfcfcf;border-bottom:none;background:#eee;border-radius:3px 3px 0 0;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse}
1485 .celltoolbar{border:thin solid #cfcfcf;border-bottom:none;background:#eee;border-radius:3px 3px 0 0;width:100%;-webkit-box-pack:end;height:22px;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch;-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:column-reverse}
1486 1486 .ctb_hideshow{display:none;vertical-align:bottom;padding-right:2px}
1487 1487 .celltoolbar>div{padding-top:0}
1488 1488 .ctb_global_show .ctb_show.ctb_hideshow{display:block}
1489 1489 .ctb_global_show .ctb_show+.input_area,.ctb_global_show .ctb_show+div.text_cell_input{border-top-right-radius:0;border-top-left-radius:0}
1490 1490 .celltoolbar .button_container select{margin:10px;margin-top:1px;margin-bottom:0;padding:0;font-size:87%;width:auto;display:inline-block;height:18px;line-height:18px;vertical-align:top}
1491 1491 .celltoolbar label{display:inline-block;height:15px;line-height:15px;vertical-align:top}
1492 1492 .celltoolbar label span{font-size:85%}
1493 1493 .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px}
1494 1494 .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px}
1495 1495 .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad}
1496 1496 .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000}
1497 1497 .completions select option.context{color:#0064cd}
1498 1498 #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px}
1499 1499 #menubar .navbar{margin-bottom:8px}
1500 1500 .nav-wrapper{border-bottom:1px solid #d4d4d4}
1501 1501 #menubar li.dropdown{line-height:12px}
1502 1502 i.menu-icon{padding-top:4px}
1503 1503 ul#help_menu li a{overflow:hidden;padding-right:2.2em}ul#help_menu li a i{margin-right:-1.2em}
1504 1504 #notification_area{z-index:10}
1505 1505 .notification_widget{color:#777;padding:1px 12px;margin:2px 4px;z-index:10;border:1px solid #ccc;border-radius:4px;background:rgba(240,240,240,0.5)}.notification_widget.span{padding-right:2px}
1506 1506 #indicator_area{color:#777;padding:2px 2px;margin:2px -9px 2px 4px;z-index:10}
1507 1507 div#pager_splitter{height:8px}
1508 1508 #pager-container{position:relative;padding:15px 0}
1509 1509 div#pager{overflow:auto;display:none}div#pager pre{font-size:13px;line-height:1.231em;color:#000;background-color:#f7f7f7;padding:.4em}
1510 1510 .shortcut_key{display:inline-block;width:15ex;text-align:right;font-family:monospace}
1511 1511 .shortcut_descr{display:inline-block}
1512 1512 span#save_widget{padding:0 5px;margin-top:12px}
1513 1513 span#checkpoint_status,span#autosave_status{font-size:small}
1514 1514 @media (max-width:767px){span#save_widget{font-size:small} span#checkpoint_status,span#autosave_status{font-size:x-small}}@media (max-width:767px){span#checkpoint_status,span#autosave_status{display:none}}@media (min-width:768px) and (max-width:979px){span#checkpoint_status{display:none} span#autosave_status{font-size:x-small}}.toolbar{padding:0 10px;margin-top:-5px}.toolbar select,.toolbar label{width:auto;height:26px;vertical-align:middle;margin-right:2px;margin-bottom:0;display:inline;font-size:92%;margin-left:.3em;margin-right:.3em;padding:0;padding-top:3px}
1515 1515 .toolbar .btn{padding:2px 8px}
1516 1516 .toolbar .btn-group{margin-top:0}
1517 1517 .toolbar-inner{border:none !important;-webkit-box-shadow:none !important;-moz-box-shadow:none !important;box-shadow:none !important}
1518 1518 #maintoolbar{margin-bottom:0}
1519 1519 @-moz-keyframes fadeOut{from{opacity:1} to{opacity:0}}@-webkit-keyframes fadeOut{from{opacity:1} to{opacity:0}}@-moz-keyframes fadeIn{from{opacity:0} to{opacity:1}}@-webkit-keyframes fadeIn{from{opacity:0} to{opacity:1}}.bigtooltip{overflow:auto;height:200px;-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms}
1520 1520 .smalltooltip{-webkit-transition-property:height;-webkit-transition-duration:500ms;-moz-transition-property:height;-moz-transition-duration:500ms;transition-property:height;transition-duration:500ms;text-overflow:ellipsis;overflow:hidden;height:80px}
1521 1521 .tooltipbuttons{position:absolute;padding-right:15px;top:0;right:0}
1522 1522 .tooltiptext{padding-right:30px}
1523 1523 .ipython_tooltip{max-width:700px;-webkit-animation:fadeOut 400ms;-moz-animation:fadeOut 400ms;animation:fadeOut 400ms;-webkit-animation:fadeIn 400ms;-moz-animation:fadeIn 400ms;animation:fadeIn 400ms;vertical-align:middle;background-color:#f7f7f7;overflow:visible;border:#ababab 1px solid;outline:none;padding:3px;margin:0;padding-left:7px;font-family:monospace;min-height:50px;-moz-box-shadow:0 6px 10px -1px #adadad;-webkit-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad;border-radius:4px;position:absolute;z-index:2}.ipython_tooltip a{float:right}
1524 1524 .ipython_tooltip .tooltiptext pre{border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;font-size:100%;background-color:#f7f7f7}
1525 1525 .pretooltiparrow{left:0;margin:0;top:-16px;width:40px;height:16px;overflow:hidden;position:absolute}
1526 1526 .pretooltiparrow:before{background-color:#f7f7f7;border:1px #ababab solid;z-index:11;content:"";position:absolute;left:15px;top:10px;width:25px;height:25px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg)}
@@ -1,11 +1,12 b''
1 1 from .widget import Widget, DOMWidget, CallbackDispatcher
2 2
3 3 from .widget_bool import CheckboxWidget, ToggleButtonWidget
4 4 from .widget_button import ButtonWidget
5 5 from .widget_container import ContainerWidget, PopupWidget
6 6 from .widget_float import FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget
7 7 from .widget_image import ImageWidget
8 8 from .widget_int import IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget
9 9 from .widget_selection import RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget
10 10 from .widget_selectioncontainer import TabWidget, AccordionWidget
11 11 from .widget_string import HTMLWidget, LatexWidget, TextWidget, TextareaWidget
12 from .interaction import interact, interactive, fixed
@@ -1,60 +1,60 b''
1 1 """FloatWidget class.
2 2
3 3 Represents an unbounded float using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, CFloat, Bool, List, Enum
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class _FloatWidget(DOMWidget):
23 23 value = CFloat(0.0, help="Float value", sync=True)
24 24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
25 25 description = Unicode(help="Description of the value this widget represents", sync=True)
26 26
27 27
28 28 class _BoundedFloatWidget(_FloatWidget):
29 29 max = CFloat(100.0, help="Max value", sync=True)
30 30 min = CFloat(0.0, help="Min value", sync=True)
31 31 step = CFloat(0.1, help="Minimum step that the value can take (ignored by some views)", sync=True)
32 32
33 33 def __init__(self, *pargs, **kwargs):
34 34 """Constructor"""
35 35 DOMWidget.__init__(self, *pargs, **kwargs)
36 36 self.on_trait_change(self._validate, ['value', 'min', 'max'])
37 37
38 38 def _validate(self, name, old, new):
39 39 """Validate value, max, min."""
40 40 if self.min > new or new > self.max:
41 41 self.value = min(max(new, self.min), self.max)
42 42
43 43
44 44 class FloatTextWidget(_FloatWidget):
45 45 _view_name = Unicode('FloatTextView', sync=True)
46 46
47 47
48 48 class BoundedFloatTextWidget(_BoundedFloatWidget):
49 49 _view_name = Unicode('FloatTextView', sync=True)
50 50
51 51
52 52 class FloatSliderWidget(_BoundedFloatWidget):
53 53 _view_name = Unicode('FloatSliderView', sync=True)
54 54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57 57
58 58
59 59 class FloatProgressWidget(_BoundedFloatWidget):
60 60 _view_name = Unicode('ProgressView', sync=True)
@@ -1,60 +1,60 b''
1 1 """IntWidget class.
2 2
3 3 Represents an unbounded int using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from .widget import DOMWidget
17 17 from IPython.utils.traitlets import Unicode, CInt, Bool, List, Enum
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Classes
21 21 #-----------------------------------------------------------------------------
22 22 class _IntWidget(DOMWidget):
23 23 value = CInt(0, help="Int value", sync=True)
24 24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
25 25 description = Unicode(help="Description of the value this widget represents", sync=True)
26 26
27 27
28 28 class _BoundedIntWidget(_IntWidget):
29 29 step = CInt(1, help="Minimum step that the value can take (ignored by some views)", sync=True)
30 30 max = CInt(100, help="Max value", sync=True)
31 31 min = CInt(0, help="Min value", sync=True)
32 32
33 33 def __init__(self, *pargs, **kwargs):
34 34 """Constructor"""
35 35 DOMWidget.__init__(self, *pargs, **kwargs)
36 36 self.on_trait_change(self._validate, ['value', 'min', 'max'])
37 37
38 38 def _validate(self, name, old, new):
39 39 """Validate value, max, min."""
40 40 if self.min > new or new > self.max:
41 41 self.value = min(max(new, self.min), self.max)
42 42
43 43
44 44 class IntTextWidget(_IntWidget):
45 45 _view_name = Unicode('IntTextView', sync=True)
46 46
47 47
48 48 class BoundedIntTextWidget(_BoundedIntWidget):
49 49 _view_name = Unicode('IntTextView', sync=True)
50 50
51 51
52 52 class IntSliderWidget(_BoundedIntWidget):
53 53 _view_name = Unicode('IntSliderView', sync=True)
54 54 orientation = Enum([u'horizontal', u'vertical'], u'horizontal',
55 55 help="Vertical or horizontal.", sync=True)
56 readout = Bool(False, help="Display the current value of the slider next to it.", sync=True)
56 readout = Bool(True, help="Display the current value of the slider next to it.", sync=True)
57 57
58 58
59 59 class IntProgressWidget(_BoundedIntWidget):
60 60 _view_name = Unicode('ProgressView', sync=True)
@@ -1,194 +1,201 b''
1 1 """ A kernel client for in-process kernels. """
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2012 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # IPython imports
15 15 from IPython.kernel.channelsabc import (
16 16 ShellChannelABC, IOPubChannelABC,
17 17 HBChannelABC, StdInChannelABC,
18 18 )
19 19
20 20 # Local imports
21 21 from .socket import DummySocket
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Channel classes
25 25 #-----------------------------------------------------------------------------
26 26
27 27 class InProcessChannel(object):
28 28 """Base class for in-process channels."""
29 29 proxy_methods = []
30 30
31 31 def __init__(self, client):
32 32 super(InProcessChannel, self).__init__()
33 33 self.client = client
34 34 self._is_alive = False
35 35
36 36 #--------------------------------------------------------------------------
37 37 # Channel interface
38 38 #--------------------------------------------------------------------------
39 39
40 40 def is_alive(self):
41 41 return self._is_alive
42 42
43 43 def start(self):
44 44 self._is_alive = True
45 45
46 46 def stop(self):
47 47 self._is_alive = False
48 48
49 49 def call_handlers(self, msg):
50 50 """ This method is called in the main thread when a message arrives.
51 51
52 52 Subclasses should override this method to handle incoming messages.
53 53 """
54 54 raise NotImplementedError('call_handlers must be defined in a subclass.')
55 55
56 56 #--------------------------------------------------------------------------
57 57 # InProcessChannel interface
58 58 #--------------------------------------------------------------------------
59 59
60 60 def call_handlers_later(self, *args, **kwds):
61 61 """ Call the message handlers later.
62 62
63 63 The default implementation just calls the handlers immediately, but this
64 64 method exists so that GUI toolkits can defer calling the handlers until
65 65 after the event loop has run, as expected by GUI frontends.
66 66 """
67 67 self.call_handlers(*args, **kwds)
68 68
69 69 def process_events(self):
70 70 """ Process any pending GUI events.
71 71
72 72 This method will be never be called from a frontend without an event
73 73 loop (e.g., a terminal frontend).
74 74 """
75 75 raise NotImplementedError
76 76
77 77
78 78 class InProcessShellChannel(InProcessChannel):
79 79 """See `IPython.kernel.channels.ShellChannel` for docstrings."""
80 80
81 81 # flag for whether execute requests should be allowed to call raw_input
82 82 allow_stdin = True
83 83 proxy_methods = [
84 84 'execute',
85 85 'complete',
86 86 'object_info',
87 87 'history',
88 88 'shutdown',
89 'kernel_info',
89 90 ]
90 91
91 92 #--------------------------------------------------------------------------
92 93 # ShellChannel interface
93 94 #--------------------------------------------------------------------------
94 95
95 96 def execute(self, code, silent=False, store_history=True,
96 97 user_variables=[], user_expressions={}, allow_stdin=None):
97 98 if allow_stdin is None:
98 99 allow_stdin = self.allow_stdin
99 100 content = dict(code=code, silent=silent, store_history=store_history,
100 101 user_variables=user_variables,
101 102 user_expressions=user_expressions,
102 103 allow_stdin=allow_stdin)
103 104 msg = self.client.session.msg('execute_request', content)
104 105 self._dispatch_to_kernel(msg)
105 106 return msg['header']['msg_id']
106 107
107 108 def complete(self, text, line, cursor_pos, block=None):
108 109 content = dict(text=text, line=line, block=block, cursor_pos=cursor_pos)
109 110 msg = self.client.session.msg('complete_request', content)
110 111 self._dispatch_to_kernel(msg)
111 112 return msg['header']['msg_id']
112 113
113 114 def object_info(self, oname, detail_level=0):
114 115 content = dict(oname=oname, detail_level=detail_level)
115 116 msg = self.client.session.msg('object_info_request', content)
116 117 self._dispatch_to_kernel(msg)
117 118 return msg['header']['msg_id']
118 119
119 120 def history(self, raw=True, output=False, hist_access_type='range', **kwds):
120 121 content = dict(raw=raw, output=output,
121 122 hist_access_type=hist_access_type, **kwds)
122 123 msg = self.client.session.msg('history_request', content)
123 124 self._dispatch_to_kernel(msg)
124 125 return msg['header']['msg_id']
125 126
126 127 def shutdown(self, restart=False):
127 128 # FIXME: What to do here?
128 129 raise NotImplementedError('Cannot shutdown in-process kernel')
129 130
131 def kernel_info(self):
132 """Request kernel info."""
133 msg = self.client.session.msg('kernel_info_request')
134 self._dispatch_to_kernel(msg)
135 return msg['header']['msg_id']
136
130 137 #--------------------------------------------------------------------------
131 138 # Protected interface
132 139 #--------------------------------------------------------------------------
133 140
134 141 def _dispatch_to_kernel(self, msg):
135 142 """ Send a message to the kernel and handle a reply.
136 143 """
137 144 kernel = self.client.kernel
138 145 if kernel is None:
139 146 raise RuntimeError('Cannot send request. No kernel exists.')
140 147
141 148 stream = DummySocket()
142 149 self.client.session.send(stream, msg)
143 150 msg_parts = stream.recv_multipart()
144 151 kernel.dispatch_shell(stream, msg_parts)
145 152
146 153 idents, reply_msg = self.client.session.recv(stream, copy=False)
147 154 self.call_handlers_later(reply_msg)
148 155
149 156
150 157 class InProcessIOPubChannel(InProcessChannel):
151 158 """See `IPython.kernel.channels.IOPubChannel` for docstrings."""
152 159
153 160 def flush(self, timeout=1.0):
154 161 pass
155 162
156 163
157 164 class InProcessStdInChannel(InProcessChannel):
158 165 """See `IPython.kernel.channels.StdInChannel` for docstrings."""
159 166
160 167 proxy_methods = ['input']
161 168
162 169 def input(self, string):
163 170 kernel = self.client.kernel
164 171 if kernel is None:
165 172 raise RuntimeError('Cannot send input reply. No kernel exists.')
166 173 kernel.raw_input_str = string
167 174
168 175
169 176 class InProcessHBChannel(InProcessChannel):
170 177 """See `IPython.kernel.channels.HBChannel` for docstrings."""
171 178
172 179 time_to_dead = 3.0
173 180
174 181 def __init__(self, *args, **kwds):
175 182 super(InProcessHBChannel, self).__init__(*args, **kwds)
176 183 self._pause = True
177 184
178 185 def pause(self):
179 186 self._pause = True
180 187
181 188 def unpause(self):
182 189 self._pause = False
183 190
184 191 def is_beating(self):
185 192 return not self._pause
186 193
187 194 #-----------------------------------------------------------------------------
188 195 # ABC Registration
189 196 #-----------------------------------------------------------------------------
190 197
191 198 ShellChannelABC.register(InProcessShellChannel)
192 199 IOPubChannelABC.register(InProcessIOPubChannel)
193 200 HBChannelABC.register(InProcessHBChannel)
194 201 StdInChannelABC.register(InProcessStdInChannel)
@@ -1,249 +1,264 b''
1 1 # coding: utf-8
2 2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 3 import functools
4 4 import os
5 5 import sys
6 6 import re
7 7 import types
8 8
9 9 from .encoding import DEFAULT_ENCODING
10 10
11 11 orig_open = open
12 12
13 13 def no_code(x, encoding=None):
14 14 return x
15 15
16 16 def decode(s, encoding=None):
17 17 encoding = encoding or DEFAULT_ENCODING
18 18 return s.decode(encoding, "replace")
19 19
20 20 def encode(u, encoding=None):
21 21 encoding = encoding or DEFAULT_ENCODING
22 22 return u.encode(encoding, "replace")
23 23
24 24
25 25 def cast_unicode(s, encoding=None):
26 26 if isinstance(s, bytes):
27 27 return decode(s, encoding)
28 28 return s
29 29
30 30 def cast_bytes(s, encoding=None):
31 31 if not isinstance(s, bytes):
32 32 return encode(s, encoding)
33 33 return s
34 34
35 35 def _modify_str_or_docstring(str_change_func):
36 36 @functools.wraps(str_change_func)
37 37 def wrapper(func_or_str):
38 38 if isinstance(func_or_str, string_types):
39 39 func = None
40 40 doc = func_or_str
41 41 else:
42 42 func = func_or_str
43 43 doc = func.__doc__
44 44
45 45 doc = str_change_func(doc)
46 46
47 47 if func:
48 48 func.__doc__ = doc
49 49 return func
50 50 return doc
51 51 return wrapper
52 52
53 53 def safe_unicode(e):
54 54 """unicode(e) with various fallbacks. Used for exceptions, which may not be
55 55 safe to call unicode() on.
56 56 """
57 57 try:
58 58 return unicode_type(e)
59 59 except UnicodeError:
60 60 pass
61 61
62 62 try:
63 63 return str_to_unicode(str(e))
64 64 except UnicodeError:
65 65 pass
66 66
67 67 try:
68 68 return str_to_unicode(repr(e))
69 69 except UnicodeError:
70 70 pass
71 71
72 72 return u'Unrecoverably corrupt evalue'
73 73
74 74 if sys.version_info[0] >= 3:
75 75 PY3 = True
76 76
77 77 # keep reference to builtin_mod because the kernel overrides that value
78 78 # to forward requests to a frontend.
79 79 def input(prompt=''):
80 80 return builtin_mod.input(prompt)
81 81
82 82 builtin_mod_name = "builtins"
83 83 import builtins as builtin_mod
84 84
85 85 str_to_unicode = no_code
86 86 unicode_to_str = no_code
87 87 str_to_bytes = encode
88 88 bytes_to_str = decode
89 89 cast_bytes_py2 = no_code
90 90 cast_unicode_py2 = no_code
91 91
92 92 string_types = (str,)
93 93 unicode_type = str
94 94
95 95 def isidentifier(s, dotted=False):
96 96 if dotted:
97 97 return all(isidentifier(a) for a in s.split("."))
98 98 return s.isidentifier()
99 99
100 100 open = orig_open
101 101 xrange = range
102 102 def iteritems(d): return iter(d.items())
103 103 def itervalues(d): return iter(d.values())
104 104 getcwd = os.getcwd
105 105
106 106 MethodType = types.MethodType
107 107
108 108 def execfile(fname, glob, loc=None):
109 109 loc = loc if (loc is not None) else glob
110 110 with open(fname, 'rb') as f:
111 111 exec(compile(f.read(), fname, 'exec'), glob, loc)
112 112
113 113 # Refactor print statements in doctests.
114 114 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
115 115 def _print_statement_sub(match):
116 116 expr = match.groups('expr')
117 117 return "print(%s)" % expr
118 118
119 119 @_modify_str_or_docstring
120 120 def doctest_refactor_print(doc):
121 121 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
122 122 unfortunately doesn't pick up on our doctests.
123 123
124 124 Can accept a string or a function, so it can be used as a decorator."""
125 125 return _print_statement_re.sub(_print_statement_sub, doc)
126 126
127 127 # Abstract u'abc' syntax:
128 128 @_modify_str_or_docstring
129 129 def u_format(s):
130 130 """"{u}'abc'" --> "'abc'" (Python 3)
131 131
132 132 Accepts a string or a function, so it can be used as a decorator."""
133 133 return s.format(u='')
134 134
135 135 else:
136 136 PY3 = False
137 137
138 138 # keep reference to builtin_mod because the kernel overrides that value
139 139 # to forward requests to a frontend.
140 140 def input(prompt=''):
141 141 return builtin_mod.raw_input(prompt)
142 142
143 143 builtin_mod_name = "__builtin__"
144 144 import __builtin__ as builtin_mod
145 145
146 146 str_to_unicode = decode
147 147 unicode_to_str = encode
148 148 str_to_bytes = no_code
149 149 bytes_to_str = no_code
150 150 cast_bytes_py2 = cast_bytes
151 151 cast_unicode_py2 = cast_unicode
152 152
153 153 string_types = (str, unicode)
154 154 unicode_type = unicode
155 155
156 156 import re
157 157 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
158 158 def isidentifier(s, dotted=False):
159 159 if dotted:
160 160 return all(isidentifier(a) for a in s.split("."))
161 161 return bool(_name_re.match(s))
162 162
163 163 class open(object):
164 164 """Wrapper providing key part of Python 3 open() interface."""
165 165 def __init__(self, fname, mode="r", encoding="utf-8"):
166 166 self.f = orig_open(fname, mode)
167 167 self.enc = encoding
168 168
169 169 def write(self, s):
170 170 return self.f.write(s.encode(self.enc))
171 171
172 172 def read(self, size=-1):
173 173 return self.f.read(size).decode(self.enc)
174 174
175 175 def close(self):
176 176 return self.f.close()
177 177
178 178 def __enter__(self):
179 179 return self
180 180
181 181 def __exit__(self, etype, value, traceback):
182 182 self.f.close()
183 183
184 184 xrange = xrange
185 185 def iteritems(d): return d.iteritems()
186 186 def itervalues(d): return d.itervalues()
187 187 getcwd = os.getcwdu
188 188
189 189 def MethodType(func, instance):
190 190 return types.MethodType(func, instance, type(instance))
191 191
192 192 def doctest_refactor_print(func_or_str):
193 193 return func_or_str
194 194
195 195
196 196 # Abstract u'abc' syntax:
197 197 @_modify_str_or_docstring
198 198 def u_format(s):
199 199 """"{u}'abc'" --> "u'abc'" (Python 2)
200 200
201 201 Accepts a string or a function, so it can be used as a decorator."""
202 202 return s.format(u='u')
203 203
204 204 if sys.platform == 'win32':
205 205 def execfile(fname, glob=None, loc=None):
206 206 loc = loc if (loc is not None) else glob
207 207 # The rstrip() is necessary b/c trailing whitespace in files will
208 208 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
209 209 # but we still support 2.6). See issue 1027.
210 210 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
211 211 # compile converts unicode filename to str assuming
212 212 # ascii. Let's do the conversion before calling compile
213 213 if isinstance(fname, unicode):
214 214 filename = unicode_to_str(fname)
215 215 else:
216 216 filename = fname
217 217 exec(compile(scripttext, filename, 'exec'), glob, loc)
218 218 else:
219 219 def execfile(fname, *where):
220 220 if isinstance(fname, unicode):
221 221 filename = fname.encode(sys.getfilesystemencoding())
222 222 else:
223 223 filename = fname
224 224 builtin_mod.execfile(filename, *where)
225 225
226
227 def annotate(**kwargs):
228 """Python 3 compatible function annotation for Python 2."""
229 if not kwargs:
230 raise ValueError('annotations must be provided as keyword arguments')
231 def dec(f):
232 if hasattr(f, '__annotations__'):
233 for k, v in kwargs.items():
234 f.__annotations__[k] = v
235 else:
236 f.__annotations__ = kwargs
237 return f
238 return dec
239
240
226 241 # Parts below taken from six:
227 242 # Copyright (c) 2010-2013 Benjamin Peterson
228 243 #
229 244 # Permission is hereby granted, free of charge, to any person obtaining a copy
230 245 # of this software and associated documentation files (the "Software"), to deal
231 246 # in the Software without restriction, including without limitation the rights
232 247 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
233 248 # copies of the Software, and to permit persons to whom the Software is
234 249 # furnished to do so, subject to the following conditions:
235 250 #
236 251 # The above copyright notice and this permission notice shall be included in all
237 252 # copies or substantial portions of the Software.
238 253 #
239 254 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
240 255 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
241 256 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
242 257 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
243 258 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
244 259 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
245 260 # SOFTWARE.
246 261
247 262 def with_metaclass(meta, *bases):
248 263 """Create a base class with a metaclass."""
249 264 return meta("_NewBase", bases, {})
@@ -1,1075 +1,1075 b''
1 1 # encoding: utf-8
2 2 """
3 3 Tests for IPython.utils.traitlets.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Enthought, Inc. Some of the code in this file comes from enthought.traits
9 9 and is licensed under the BSD license. Also, many of the ideas also come
10 10 from enthought.traits even though our implementation is very different.
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import re
25 25 import sys
26 26 from unittest import TestCase
27 27
28 28 import nose.tools as nt
29 29 from nose import SkipTest
30 30
31 31 from IPython.utils.traitlets import (
32 32 HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict,
33 33 Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError,
34 34 Undefined, Type, This, Instance, TCPAddress, List, Tuple,
35 ObjectName, DottedObjectName, CRegExp, bind
35 ObjectName, DottedObjectName, CRegExp, link
36 36 )
37 37 from IPython.utils import py3compat
38 38 from IPython.testing.decorators import skipif
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Helper classes for testing
42 42 #-----------------------------------------------------------------------------
43 43
44 44
45 45 class HasTraitsStub(HasTraits):
46 46
47 47 def _notify_trait(self, name, old, new):
48 48 self._notify_name = name
49 49 self._notify_old = old
50 50 self._notify_new = new
51 51
52 52
53 53 #-----------------------------------------------------------------------------
54 54 # Test classes
55 55 #-----------------------------------------------------------------------------
56 56
57 57
58 58 class TestTraitType(TestCase):
59 59
60 60 def test_get_undefined(self):
61 61 class A(HasTraits):
62 62 a = TraitType
63 63 a = A()
64 64 self.assertEqual(a.a, Undefined)
65 65
66 66 def test_set(self):
67 67 class A(HasTraitsStub):
68 68 a = TraitType
69 69
70 70 a = A()
71 71 a.a = 10
72 72 self.assertEqual(a.a, 10)
73 73 self.assertEqual(a._notify_name, 'a')
74 74 self.assertEqual(a._notify_old, Undefined)
75 75 self.assertEqual(a._notify_new, 10)
76 76
77 77 def test_validate(self):
78 78 class MyTT(TraitType):
79 79 def validate(self, inst, value):
80 80 return -1
81 81 class A(HasTraitsStub):
82 82 tt = MyTT
83 83
84 84 a = A()
85 85 a.tt = 10
86 86 self.assertEqual(a.tt, -1)
87 87
88 88 def test_default_validate(self):
89 89 class MyIntTT(TraitType):
90 90 def validate(self, obj, value):
91 91 if isinstance(value, int):
92 92 return value
93 93 self.error(obj, value)
94 94 class A(HasTraits):
95 95 tt = MyIntTT(10)
96 96 a = A()
97 97 self.assertEqual(a.tt, 10)
98 98
99 99 # Defaults are validated when the HasTraits is instantiated
100 100 class B(HasTraits):
101 101 tt = MyIntTT('bad default')
102 102 self.assertRaises(TraitError, B)
103 103
104 104 def test_is_valid_for(self):
105 105 class MyTT(TraitType):
106 106 def is_valid_for(self, value):
107 107 return True
108 108 class A(HasTraits):
109 109 tt = MyTT
110 110
111 111 a = A()
112 112 a.tt = 10
113 113 self.assertEqual(a.tt, 10)
114 114
115 115 def test_value_for(self):
116 116 class MyTT(TraitType):
117 117 def value_for(self, value):
118 118 return 20
119 119 class A(HasTraits):
120 120 tt = MyTT
121 121
122 122 a = A()
123 123 a.tt = 10
124 124 self.assertEqual(a.tt, 20)
125 125
126 126 def test_info(self):
127 127 class A(HasTraits):
128 128 tt = TraitType
129 129 a = A()
130 130 self.assertEqual(A.tt.info(), 'any value')
131 131
132 132 def test_error(self):
133 133 class A(HasTraits):
134 134 tt = TraitType
135 135 a = A()
136 136 self.assertRaises(TraitError, A.tt.error, a, 10)
137 137
138 138 def test_dynamic_initializer(self):
139 139 class A(HasTraits):
140 140 x = Int(10)
141 141 def _x_default(self):
142 142 return 11
143 143 class B(A):
144 144 x = Int(20)
145 145 class C(A):
146 146 def _x_default(self):
147 147 return 21
148 148
149 149 a = A()
150 150 self.assertEqual(a._trait_values, {})
151 151 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
152 152 self.assertEqual(a.x, 11)
153 153 self.assertEqual(a._trait_values, {'x': 11})
154 154 b = B()
155 155 self.assertEqual(b._trait_values, {'x': 20})
156 156 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
157 157 self.assertEqual(b.x, 20)
158 158 c = C()
159 159 self.assertEqual(c._trait_values, {})
160 160 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
161 161 self.assertEqual(c.x, 21)
162 162 self.assertEqual(c._trait_values, {'x': 21})
163 163 # Ensure that the base class remains unmolested when the _default
164 164 # initializer gets overridden in a subclass.
165 165 a = A()
166 166 c = C()
167 167 self.assertEqual(a._trait_values, {})
168 168 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
169 169 self.assertEqual(a.x, 11)
170 170 self.assertEqual(a._trait_values, {'x': 11})
171 171
172 172
173 173
174 174 class TestHasTraitsMeta(TestCase):
175 175
176 176 def test_metaclass(self):
177 177 self.assertEqual(type(HasTraits), MetaHasTraits)
178 178
179 179 class A(HasTraits):
180 180 a = Int
181 181
182 182 a = A()
183 183 self.assertEqual(type(a.__class__), MetaHasTraits)
184 184 self.assertEqual(a.a,0)
185 185 a.a = 10
186 186 self.assertEqual(a.a,10)
187 187
188 188 class B(HasTraits):
189 189 b = Int()
190 190
191 191 b = B()
192 192 self.assertEqual(b.b,0)
193 193 b.b = 10
194 194 self.assertEqual(b.b,10)
195 195
196 196 class C(HasTraits):
197 197 c = Int(30)
198 198
199 199 c = C()
200 200 self.assertEqual(c.c,30)
201 201 c.c = 10
202 202 self.assertEqual(c.c,10)
203 203
204 204 def test_this_class(self):
205 205 class A(HasTraits):
206 206 t = This()
207 207 tt = This()
208 208 class B(A):
209 209 tt = This()
210 210 ttt = This()
211 211 self.assertEqual(A.t.this_class, A)
212 212 self.assertEqual(B.t.this_class, A)
213 213 self.assertEqual(B.tt.this_class, B)
214 214 self.assertEqual(B.ttt.this_class, B)
215 215
216 216 class TestHasTraitsNotify(TestCase):
217 217
218 218 def setUp(self):
219 219 self._notify1 = []
220 220 self._notify2 = []
221 221
222 222 def notify1(self, name, old, new):
223 223 self._notify1.append((name, old, new))
224 224
225 225 def notify2(self, name, old, new):
226 226 self._notify2.append((name, old, new))
227 227
228 228 def test_notify_all(self):
229 229
230 230 class A(HasTraits):
231 231 a = Int
232 232 b = Float
233 233
234 234 a = A()
235 235 a.on_trait_change(self.notify1)
236 236 a.a = 0
237 237 self.assertEqual(len(self._notify1),0)
238 238 a.b = 0.0
239 239 self.assertEqual(len(self._notify1),0)
240 240 a.a = 10
241 241 self.assertTrue(('a',0,10) in self._notify1)
242 242 a.b = 10.0
243 243 self.assertTrue(('b',0.0,10.0) in self._notify1)
244 244 self.assertRaises(TraitError,setattr,a,'a','bad string')
245 245 self.assertRaises(TraitError,setattr,a,'b','bad string')
246 246 self._notify1 = []
247 247 a.on_trait_change(self.notify1,remove=True)
248 248 a.a = 20
249 249 a.b = 20.0
250 250 self.assertEqual(len(self._notify1),0)
251 251
252 252 def test_notify_one(self):
253 253
254 254 class A(HasTraits):
255 255 a = Int
256 256 b = Float
257 257
258 258 a = A()
259 259 a.on_trait_change(self.notify1, 'a')
260 260 a.a = 0
261 261 self.assertEqual(len(self._notify1),0)
262 262 a.a = 10
263 263 self.assertTrue(('a',0,10) in self._notify1)
264 264 self.assertRaises(TraitError,setattr,a,'a','bad string')
265 265
266 266 def test_subclass(self):
267 267
268 268 class A(HasTraits):
269 269 a = Int
270 270
271 271 class B(A):
272 272 b = Float
273 273
274 274 b = B()
275 275 self.assertEqual(b.a,0)
276 276 self.assertEqual(b.b,0.0)
277 277 b.a = 100
278 278 b.b = 100.0
279 279 self.assertEqual(b.a,100)
280 280 self.assertEqual(b.b,100.0)
281 281
282 282 def test_notify_subclass(self):
283 283
284 284 class A(HasTraits):
285 285 a = Int
286 286
287 287 class B(A):
288 288 b = Float
289 289
290 290 b = B()
291 291 b.on_trait_change(self.notify1, 'a')
292 292 b.on_trait_change(self.notify2, 'b')
293 293 b.a = 0
294 294 b.b = 0.0
295 295 self.assertEqual(len(self._notify1),0)
296 296 self.assertEqual(len(self._notify2),0)
297 297 b.a = 10
298 298 b.b = 10.0
299 299 self.assertTrue(('a',0,10) in self._notify1)
300 300 self.assertTrue(('b',0.0,10.0) in self._notify2)
301 301
302 302 def test_static_notify(self):
303 303
304 304 class A(HasTraits):
305 305 a = Int
306 306 _notify1 = []
307 307 def _a_changed(self, name, old, new):
308 308 self._notify1.append((name, old, new))
309 309
310 310 a = A()
311 311 a.a = 0
312 312 # This is broken!!!
313 313 self.assertEqual(len(a._notify1),0)
314 314 a.a = 10
315 315 self.assertTrue(('a',0,10) in a._notify1)
316 316
317 317 class B(A):
318 318 b = Float
319 319 _notify2 = []
320 320 def _b_changed(self, name, old, new):
321 321 self._notify2.append((name, old, new))
322 322
323 323 b = B()
324 324 b.a = 10
325 325 b.b = 10.0
326 326 self.assertTrue(('a',0,10) in b._notify1)
327 327 self.assertTrue(('b',0.0,10.0) in b._notify2)
328 328
329 329 def test_notify_args(self):
330 330
331 331 def callback0():
332 332 self.cb = ()
333 333 def callback1(name):
334 334 self.cb = (name,)
335 335 def callback2(name, new):
336 336 self.cb = (name, new)
337 337 def callback3(name, old, new):
338 338 self.cb = (name, old, new)
339 339
340 340 class A(HasTraits):
341 341 a = Int
342 342
343 343 a = A()
344 344 a.on_trait_change(callback0, 'a')
345 345 a.a = 10
346 346 self.assertEqual(self.cb,())
347 347 a.on_trait_change(callback0, 'a', remove=True)
348 348
349 349 a.on_trait_change(callback1, 'a')
350 350 a.a = 100
351 351 self.assertEqual(self.cb,('a',))
352 352 a.on_trait_change(callback1, 'a', remove=True)
353 353
354 354 a.on_trait_change(callback2, 'a')
355 355 a.a = 1000
356 356 self.assertEqual(self.cb,('a',1000))
357 357 a.on_trait_change(callback2, 'a', remove=True)
358 358
359 359 a.on_trait_change(callback3, 'a')
360 360 a.a = 10000
361 361 self.assertEqual(self.cb,('a',1000,10000))
362 362 a.on_trait_change(callback3, 'a', remove=True)
363 363
364 364 self.assertEqual(len(a._trait_notifiers['a']),0)
365 365
366 366 def test_notify_only_once(self):
367 367
368 368 class A(HasTraits):
369 369 listen_to = ['a']
370 370
371 371 a = Int(0)
372 372 b = 0
373 373
374 374 def __init__(self, **kwargs):
375 375 super(A, self).__init__(**kwargs)
376 376 self.on_trait_change(self.listener1, ['a'])
377 377
378 378 def listener1(self, name, old, new):
379 379 self.b += 1
380 380
381 381 class B(A):
382 382
383 383 c = 0
384 384 d = 0
385 385
386 386 def __init__(self, **kwargs):
387 387 super(B, self).__init__(**kwargs)
388 388 self.on_trait_change(self.listener2)
389 389
390 390 def listener2(self, name, old, new):
391 391 self.c += 1
392 392
393 393 def _a_changed(self, name, old, new):
394 394 self.d += 1
395 395
396 396 b = B()
397 397 b.a += 1
398 398 self.assertEqual(b.b, b.c)
399 399 self.assertEqual(b.b, b.d)
400 400 b.a += 1
401 401 self.assertEqual(b.b, b.c)
402 402 self.assertEqual(b.b, b.d)
403 403
404 404
405 405 class TestHasTraits(TestCase):
406 406
407 407 def test_trait_names(self):
408 408 class A(HasTraits):
409 409 i = Int
410 410 f = Float
411 411 a = A()
412 412 self.assertEqual(sorted(a.trait_names()),['f','i'])
413 413 self.assertEqual(sorted(A.class_trait_names()),['f','i'])
414 414
415 415 def test_trait_metadata(self):
416 416 class A(HasTraits):
417 417 i = Int(config_key='MY_VALUE')
418 418 a = A()
419 419 self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
420 420
421 421 def test_traits(self):
422 422 class A(HasTraits):
423 423 i = Int
424 424 f = Float
425 425 a = A()
426 426 self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
427 427 self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
428 428
429 429 def test_traits_metadata(self):
430 430 class A(HasTraits):
431 431 i = Int(config_key='VALUE1', other_thing='VALUE2')
432 432 f = Float(config_key='VALUE3', other_thing='VALUE2')
433 433 j = Int(0)
434 434 a = A()
435 435 self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
436 436 traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
437 437 self.assertEqual(traits, dict(i=A.i))
438 438
439 439 # This passes, but it shouldn't because I am replicating a bug in
440 440 # traits.
441 441 traits = a.traits(config_key=lambda v: True)
442 442 self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
443 443
444 444 def test_init(self):
445 445 class A(HasTraits):
446 446 i = Int()
447 447 x = Float()
448 448 a = A(i=1, x=10.0)
449 449 self.assertEqual(a.i, 1)
450 450 self.assertEqual(a.x, 10.0)
451 451
452 452 def test_positional_args(self):
453 453 class A(HasTraits):
454 454 i = Int(0)
455 455 def __init__(self, i):
456 456 super(A, self).__init__()
457 457 self.i = i
458 458
459 459 a = A(5)
460 460 self.assertEqual(a.i, 5)
461 461 # should raise TypeError if no positional arg given
462 462 self.assertRaises(TypeError, A)
463 463
464 464 #-----------------------------------------------------------------------------
465 465 # Tests for specific trait types
466 466 #-----------------------------------------------------------------------------
467 467
468 468
469 469 class TestType(TestCase):
470 470
471 471 def test_default(self):
472 472
473 473 class B(object): pass
474 474 class A(HasTraits):
475 475 klass = Type
476 476
477 477 a = A()
478 478 self.assertEqual(a.klass, None)
479 479
480 480 a.klass = B
481 481 self.assertEqual(a.klass, B)
482 482 self.assertRaises(TraitError, setattr, a, 'klass', 10)
483 483
484 484 def test_value(self):
485 485
486 486 class B(object): pass
487 487 class C(object): pass
488 488 class A(HasTraits):
489 489 klass = Type(B)
490 490
491 491 a = A()
492 492 self.assertEqual(a.klass, B)
493 493 self.assertRaises(TraitError, setattr, a, 'klass', C)
494 494 self.assertRaises(TraitError, setattr, a, 'klass', object)
495 495 a.klass = B
496 496
497 497 def test_allow_none(self):
498 498
499 499 class B(object): pass
500 500 class C(B): pass
501 501 class A(HasTraits):
502 502 klass = Type(B, allow_none=False)
503 503
504 504 a = A()
505 505 self.assertEqual(a.klass, B)
506 506 self.assertRaises(TraitError, setattr, a, 'klass', None)
507 507 a.klass = C
508 508 self.assertEqual(a.klass, C)
509 509
510 510 def test_validate_klass(self):
511 511
512 512 class A(HasTraits):
513 513 klass = Type('no strings allowed')
514 514
515 515 self.assertRaises(ImportError, A)
516 516
517 517 class A(HasTraits):
518 518 klass = Type('rub.adub.Duck')
519 519
520 520 self.assertRaises(ImportError, A)
521 521
522 522 def test_validate_default(self):
523 523
524 524 class B(object): pass
525 525 class A(HasTraits):
526 526 klass = Type('bad default', B)
527 527
528 528 self.assertRaises(ImportError, A)
529 529
530 530 class C(HasTraits):
531 531 klass = Type(None, B, allow_none=False)
532 532
533 533 self.assertRaises(TraitError, C)
534 534
535 535 def test_str_klass(self):
536 536
537 537 class A(HasTraits):
538 538 klass = Type('IPython.utils.ipstruct.Struct')
539 539
540 540 from IPython.utils.ipstruct import Struct
541 541 a = A()
542 542 a.klass = Struct
543 543 self.assertEqual(a.klass, Struct)
544 544
545 545 self.assertRaises(TraitError, setattr, a, 'klass', 10)
546 546
547 547 class TestInstance(TestCase):
548 548
549 549 def test_basic(self):
550 550 class Foo(object): pass
551 551 class Bar(Foo): pass
552 552 class Bah(object): pass
553 553
554 554 class A(HasTraits):
555 555 inst = Instance(Foo)
556 556
557 557 a = A()
558 558 self.assertTrue(a.inst is None)
559 559 a.inst = Foo()
560 560 self.assertTrue(isinstance(a.inst, Foo))
561 561 a.inst = Bar()
562 562 self.assertTrue(isinstance(a.inst, Foo))
563 563 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
564 564 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
565 565 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
566 566
567 567 def test_unique_default_value(self):
568 568 class Foo(object): pass
569 569 class A(HasTraits):
570 570 inst = Instance(Foo,(),{})
571 571
572 572 a = A()
573 573 b = A()
574 574 self.assertTrue(a.inst is not b.inst)
575 575
576 576 def test_args_kw(self):
577 577 class Foo(object):
578 578 def __init__(self, c): self.c = c
579 579 class Bar(object): pass
580 580 class Bah(object):
581 581 def __init__(self, c, d):
582 582 self.c = c; self.d = d
583 583
584 584 class A(HasTraits):
585 585 inst = Instance(Foo, (10,))
586 586 a = A()
587 587 self.assertEqual(a.inst.c, 10)
588 588
589 589 class B(HasTraits):
590 590 inst = Instance(Bah, args=(10,), kw=dict(d=20))
591 591 b = B()
592 592 self.assertEqual(b.inst.c, 10)
593 593 self.assertEqual(b.inst.d, 20)
594 594
595 595 class C(HasTraits):
596 596 inst = Instance(Foo)
597 597 c = C()
598 598 self.assertTrue(c.inst is None)
599 599
600 600 def test_bad_default(self):
601 601 class Foo(object): pass
602 602
603 603 class A(HasTraits):
604 604 inst = Instance(Foo, allow_none=False)
605 605
606 606 self.assertRaises(TraitError, A)
607 607
608 608 def test_instance(self):
609 609 class Foo(object): pass
610 610
611 611 def inner():
612 612 class A(HasTraits):
613 613 inst = Instance(Foo())
614 614
615 615 self.assertRaises(TraitError, inner)
616 616
617 617
618 618 class TestThis(TestCase):
619 619
620 620 def test_this_class(self):
621 621 class Foo(HasTraits):
622 622 this = This
623 623
624 624 f = Foo()
625 625 self.assertEqual(f.this, None)
626 626 g = Foo()
627 627 f.this = g
628 628 self.assertEqual(f.this, g)
629 629 self.assertRaises(TraitError, setattr, f, 'this', 10)
630 630
631 631 def test_this_inst(self):
632 632 class Foo(HasTraits):
633 633 this = This()
634 634
635 635 f = Foo()
636 636 f.this = Foo()
637 637 self.assertTrue(isinstance(f.this, Foo))
638 638
639 639 def test_subclass(self):
640 640 class Foo(HasTraits):
641 641 t = This()
642 642 class Bar(Foo):
643 643 pass
644 644 f = Foo()
645 645 b = Bar()
646 646 f.t = b
647 647 b.t = f
648 648 self.assertEqual(f.t, b)
649 649 self.assertEqual(b.t, f)
650 650
651 651 def test_subclass_override(self):
652 652 class Foo(HasTraits):
653 653 t = This()
654 654 class Bar(Foo):
655 655 t = This()
656 656 f = Foo()
657 657 b = Bar()
658 658 f.t = b
659 659 self.assertEqual(f.t, b)
660 660 self.assertRaises(TraitError, setattr, b, 't', f)
661 661
662 662 class TraitTestBase(TestCase):
663 663 """A best testing class for basic trait types."""
664 664
665 665 def assign(self, value):
666 666 self.obj.value = value
667 667
668 668 def coerce(self, value):
669 669 return value
670 670
671 671 def test_good_values(self):
672 672 if hasattr(self, '_good_values'):
673 673 for value in self._good_values:
674 674 self.assign(value)
675 675 self.assertEqual(self.obj.value, self.coerce(value))
676 676
677 677 def test_bad_values(self):
678 678 if hasattr(self, '_bad_values'):
679 679 for value in self._bad_values:
680 680 try:
681 681 self.assertRaises(TraitError, self.assign, value)
682 682 except AssertionError:
683 683 assert False, value
684 684
685 685 def test_default_value(self):
686 686 if hasattr(self, '_default_value'):
687 687 self.assertEqual(self._default_value, self.obj.value)
688 688
689 689 def tearDown(self):
690 690 # restore default value after tests, if set
691 691 if hasattr(self, '_default_value'):
692 692 self.obj.value = self._default_value
693 693
694 694
695 695 class AnyTrait(HasTraits):
696 696
697 697 value = Any
698 698
699 699 class AnyTraitTest(TraitTestBase):
700 700
701 701 obj = AnyTrait()
702 702
703 703 _default_value = None
704 704 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
705 705 _bad_values = []
706 706
707 707
708 708 class IntTrait(HasTraits):
709 709
710 710 value = Int(99)
711 711
712 712 class TestInt(TraitTestBase):
713 713
714 714 obj = IntTrait()
715 715 _default_value = 99
716 716 _good_values = [10, -10]
717 717 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j,
718 718 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
719 719 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
720 720 if not py3compat.PY3:
721 721 _bad_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
722 722
723 723
724 724 class LongTrait(HasTraits):
725 725
726 726 value = Long(99 if py3compat.PY3 else long(99))
727 727
728 728 class TestLong(TraitTestBase):
729 729
730 730 obj = LongTrait()
731 731
732 732 _default_value = 99 if py3compat.PY3 else long(99)
733 733 _good_values = [10, -10]
734 734 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
735 735 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
736 736 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
737 737 u'-10.1']
738 738 if not py3compat.PY3:
739 739 # maxint undefined on py3, because int == long
740 740 _good_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
741 741 _bad_values.extend([[long(10)], (long(10),)])
742 742
743 743 @skipif(py3compat.PY3, "not relevant on py3")
744 744 def test_cast_small(self):
745 745 """Long casts ints to long"""
746 746 self.obj.value = 10
747 747 self.assertEqual(type(self.obj.value), long)
748 748
749 749
750 750 class IntegerTrait(HasTraits):
751 751 value = Integer(1)
752 752
753 753 class TestInteger(TestLong):
754 754 obj = IntegerTrait()
755 755 _default_value = 1
756 756
757 757 def coerce(self, n):
758 758 return int(n)
759 759
760 760 @skipif(py3compat.PY3, "not relevant on py3")
761 761 def test_cast_small(self):
762 762 """Integer casts small longs to int"""
763 763 if py3compat.PY3:
764 764 raise SkipTest("not relevant on py3")
765 765
766 766 self.obj.value = long(100)
767 767 self.assertEqual(type(self.obj.value), int)
768 768
769 769
770 770 class FloatTrait(HasTraits):
771 771
772 772 value = Float(99.0)
773 773
774 774 class TestFloat(TraitTestBase):
775 775
776 776 obj = FloatTrait()
777 777
778 778 _default_value = 99.0
779 779 _good_values = [10, -10, 10.1, -10.1]
780 780 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None,
781 781 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
782 782 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
783 783 if not py3compat.PY3:
784 784 _bad_values.extend([long(10), long(-10)])
785 785
786 786
787 787 class ComplexTrait(HasTraits):
788 788
789 789 value = Complex(99.0-99.0j)
790 790
791 791 class TestComplex(TraitTestBase):
792 792
793 793 obj = ComplexTrait()
794 794
795 795 _default_value = 99.0-99.0j
796 796 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
797 797 10.1j, 10.1+10.1j, 10.1-10.1j]
798 798 _bad_values = [u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
799 799 if not py3compat.PY3:
800 800 _bad_values.extend([long(10), long(-10)])
801 801
802 802
803 803 class BytesTrait(HasTraits):
804 804
805 805 value = Bytes(b'string')
806 806
807 807 class TestBytes(TraitTestBase):
808 808
809 809 obj = BytesTrait()
810 810
811 811 _default_value = b'string'
812 812 _good_values = [b'10', b'-10', b'10L',
813 813 b'-10L', b'10.1', b'-10.1', b'string']
814 814 _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
815 815 ['ten'],{'ten': 10},(10,), None, u'string']
816 816 if not py3compat.PY3:
817 817 _bad_values.extend([long(10), long(-10)])
818 818
819 819
820 820 class UnicodeTrait(HasTraits):
821 821
822 822 value = Unicode(u'unicode')
823 823
824 824 class TestUnicode(TraitTestBase):
825 825
826 826 obj = UnicodeTrait()
827 827
828 828 _default_value = u'unicode'
829 829 _good_values = ['10', '-10', '10L', '-10L', '10.1',
830 830 '-10.1', '', u'', 'string', u'string', u"€"]
831 831 _bad_values = [10, -10, 10.1, -10.1, 1j,
832 832 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
833 833 if not py3compat.PY3:
834 834 _bad_values.extend([long(10), long(-10)])
835 835
836 836
837 837 class ObjectNameTrait(HasTraits):
838 838 value = ObjectName("abc")
839 839
840 840 class TestObjectName(TraitTestBase):
841 841 obj = ObjectNameTrait()
842 842
843 843 _default_value = "abc"
844 844 _good_values = ["a", "gh", "g9", "g_", "_G", u"a345_"]
845 845 _bad_values = [1, "", u"€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
846 846 object(), object]
847 847 if sys.version_info[0] < 3:
848 848 _bad_values.append(u"þ")
849 849 else:
850 850 _good_values.append(u"þ") # þ=1 is valid in Python 3 (PEP 3131).
851 851
852 852
853 853 class DottedObjectNameTrait(HasTraits):
854 854 value = DottedObjectName("a.b")
855 855
856 856 class TestDottedObjectName(TraitTestBase):
857 857 obj = DottedObjectNameTrait()
858 858
859 859 _default_value = "a.b"
860 860 _good_values = ["A", "y.t", "y765.__repr__", "os.path.join", u"os.path.join"]
861 861 _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc."]
862 862 if sys.version_info[0] < 3:
863 863 _bad_values.append(u"t.þ")
864 864 else:
865 865 _good_values.append(u"t.þ")
866 866
867 867
868 868 class TCPAddressTrait(HasTraits):
869 869
870 870 value = TCPAddress()
871 871
872 872 class TestTCPAddress(TraitTestBase):
873 873
874 874 obj = TCPAddressTrait()
875 875
876 876 _default_value = ('127.0.0.1',0)
877 877 _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
878 878 _bad_values = [(0,0),('localhost',10.0),('localhost',-1)]
879 879
880 880 class ListTrait(HasTraits):
881 881
882 882 value = List(Int)
883 883
884 884 class TestList(TraitTestBase):
885 885
886 886 obj = ListTrait()
887 887
888 888 _default_value = []
889 889 _good_values = [[], [1], list(range(10))]
890 890 _bad_values = [10, [1,'a'], 'a', (1,2)]
891 891
892 892 class LenListTrait(HasTraits):
893 893
894 894 value = List(Int, [0], minlen=1, maxlen=2)
895 895
896 896 class TestLenList(TraitTestBase):
897 897
898 898 obj = LenListTrait()
899 899
900 900 _default_value = [0]
901 901 _good_values = [[1], list(range(2))]
902 902 _bad_values = [10, [1,'a'], 'a', (1,2), [], list(range(3))]
903 903
904 904 class TupleTrait(HasTraits):
905 905
906 906 value = Tuple(Int)
907 907
908 908 class TestTupleTrait(TraitTestBase):
909 909
910 910 obj = TupleTrait()
911 911
912 912 _default_value = None
913 913 _good_values = [(1,), None,(0,)]
914 914 _bad_values = [10, (1,2), [1],('a'), ()]
915 915
916 916 def test_invalid_args(self):
917 917 self.assertRaises(TypeError, Tuple, 5)
918 918 self.assertRaises(TypeError, Tuple, default_value='hello')
919 919 t = Tuple(Int, CBytes, default_value=(1,5))
920 920
921 921 class LooseTupleTrait(HasTraits):
922 922
923 923 value = Tuple((1,2,3))
924 924
925 925 class TestLooseTupleTrait(TraitTestBase):
926 926
927 927 obj = LooseTupleTrait()
928 928
929 929 _default_value = (1,2,3)
930 930 _good_values = [(1,), None, (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
931 931 _bad_values = [10, 'hello', [1], []]
932 932
933 933 def test_invalid_args(self):
934 934 self.assertRaises(TypeError, Tuple, 5)
935 935 self.assertRaises(TypeError, Tuple, default_value='hello')
936 936 t = Tuple(Int, CBytes, default_value=(1,5))
937 937
938 938
939 939 class MultiTupleTrait(HasTraits):
940 940
941 941 value = Tuple(Int, Bytes, default_value=[99,b'bottles'])
942 942
943 943 class TestMultiTuple(TraitTestBase):
944 944
945 945 obj = MultiTupleTrait()
946 946
947 947 _default_value = (99,b'bottles')
948 948 _good_values = [(1,b'a'), (2,b'b')]
949 949 _bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, u'a'))
950 950
951 951 class CRegExpTrait(HasTraits):
952 952
953 953 value = CRegExp(r'')
954 954
955 955 class TestCRegExp(TraitTestBase):
956 956
957 957 def coerce(self, value):
958 958 return re.compile(value)
959 959
960 960 obj = CRegExpTrait()
961 961
962 962 _default_value = re.compile(r'')
963 963 _good_values = [r'\d+', re.compile(r'\d+')]
964 964 _bad_values = [r'(', None, ()]
965 965
966 966 class DictTrait(HasTraits):
967 967 value = Dict()
968 968
969 969 def test_dict_assignment():
970 970 d = dict()
971 971 c = DictTrait()
972 972 c.value = d
973 973 d['a'] = 5
974 974 nt.assert_equal(d, c.value)
975 975 nt.assert_true(c.value is d)
976 976
977 class TestBind(TestCase):
977 class TestLink(TestCase):
978 978 def test_connect_same(self):
979 """Verify two traitlets of the same type can be bound together using bind."""
979 """Verify two traitlets of the same type can be linked together using link."""
980 980
981 981 # Create two simple classes with Int traitlets.
982 982 class A(HasTraits):
983 983 value = Int()
984 984 a = A(value=9)
985 985 b = A(value=8)
986 986
987 987 # Conenct the two classes.
988 c = bind((a, 'value'), (b, 'value'))
988 c = link((a, 'value'), (b, 'value'))
989 989
990 # Make sure the values are the same at the point of binding.
990 # Make sure the values are the same at the point of linking.
991 991 self.assertEqual(a.value, b.value)
992 992
993 993 # Change one of the values to make sure they stay in sync.
994 994 a.value = 5
995 995 self.assertEqual(a.value, b.value)
996 996 b.value = 6
997 997 self.assertEqual(a.value, b.value)
998 998
999 def test_bind_different(self):
1000 """Verify two traitlets of different types can be bound together using bind."""
999 def test_link_different(self):
1000 """Verify two traitlets of different types can be linked together using link."""
1001 1001
1002 1002 # Create two simple classes with Int traitlets.
1003 1003 class A(HasTraits):
1004 1004 value = Int()
1005 1005 class B(HasTraits):
1006 1006 count = Int()
1007 1007 a = A(value=9)
1008 1008 b = B(count=8)
1009 1009
1010 1010 # Conenct the two classes.
1011 c = bind((a, 'value'), (b, 'count'))
1011 c = link((a, 'value'), (b, 'count'))
1012 1012
1013 # Make sure the values are the same at the point of binding.
1013 # Make sure the values are the same at the point of linking.
1014 1014 self.assertEqual(a.value, b.count)
1015 1015
1016 1016 # Change one of the values to make sure they stay in sync.
1017 1017 a.value = 5
1018 1018 self.assertEqual(a.value, b.count)
1019 1019 b.count = 4
1020 1020 self.assertEqual(a.value, b.count)
1021 1021
1022 def test_unbind(self):
1023 """Verify two binded traitlets can be unbinded."""
1022 def test_unlink(self):
1023 """Verify two linked traitlets can be unlinked."""
1024 1024
1025 1025 # Create two simple classes with Int traitlets.
1026 1026 class A(HasTraits):
1027 1027 value = Int()
1028 1028 a = A(value=9)
1029 1029 b = A(value=8)
1030 1030
1031 # Conenct the two classes.
1032 c = bind((a, 'value'), (b, 'value'))
1031 # Connect the two classes.
1032 c = link((a, 'value'), (b, 'value'))
1033 1033 a.value = 4
1034 c.unbind()
1034 c.unlink()
1035 1035
1036 # Change one of the values to make sure they stay in sync.
1036 # Change one of the values to make sure they don't stay in sync.
1037 1037 a.value = 5
1038 1038 self.assertNotEqual(a.value, b.value)
1039 1039
1040 1040 def test_callbacks(self):
1041 """Verify two binded traitlets have their callbacks called once."""
1041 """Verify two linked traitlets have their callbacks called once."""
1042 1042
1043 1043 # Create two simple classes with Int traitlets.
1044 1044 class A(HasTraits):
1045 1045 value = Int()
1046 1046 class B(HasTraits):
1047 1047 count = Int()
1048 1048 a = A(value=9)
1049 1049 b = B(count=8)
1050 1050
1051 1051 # Register callbacks that count.
1052 1052 callback_count = []
1053 1053 def a_callback(name, old, new):
1054 1054 callback_count.append('a')
1055 1055 a.on_trait_change(a_callback, 'value')
1056 1056 def b_callback(name, old, new):
1057 1057 callback_count.append('b')
1058 1058 b.on_trait_change(b_callback, 'count')
1059 1059
1060 # Conenct the two classes.
1061 c = bind((a, 'value'), (b, 'count'))
1060 # Connect the two classes.
1061 c = link((a, 'value'), (b, 'count'))
1062 1062
1063 1063 # Make sure b's count was set to a's value once.
1064 1064 self.assertEqual(''.join(callback_count), 'b')
1065 1065 del callback_count[:]
1066 1066
1067 1067 # Make sure a's value was set to b's count once.
1068 1068 b.count = 5
1069 1069 self.assertEqual(''.join(callback_count), 'ba')
1070 1070 del callback_count[:]
1071 1071
1072 1072 # Make sure b's count was set to a's value once.
1073 1073 a.value = 4
1074 1074 self.assertEqual(''.join(callback_count), 'ab')
1075 1075 del callback_count[:]
@@ -1,1497 +1,1497 b''
1 1 # encoding: utf-8
2 2 """
3 3 A lightweight Traits like module.
4 4
5 5 This is designed to provide a lightweight, simple, pure Python version of
6 6 many of the capabilities of enthought.traits. This includes:
7 7
8 8 * Validation
9 9 * Type specification with defaults
10 10 * Static and dynamic notification
11 11 * Basic predefined types
12 12 * An API that is similar to enthought.traits
13 13
14 14 We don't support:
15 15
16 16 * Delegation
17 17 * Automatic GUI generation
18 18 * A full set of trait types. Most importantly, we don't provide container
19 19 traits (list, dict, tuple) that can trigger notifications if their
20 20 contents change.
21 21 * API compatibility with enthought.traits
22 22
23 23 There are also some important difference in our design:
24 24
25 25 * enthought.traits does not validate default values. We do.
26 26
27 27 We choose to create this module because we need these capabilities, but
28 28 we need them to be pure Python so they work in all Python implementations,
29 29 including Jython and IronPython.
30 30
31 31 Inheritance diagram:
32 32
33 33 .. inheritance-diagram:: IPython.utils.traitlets
34 34 :parts: 3
35 35
36 36 Authors:
37 37
38 38 * Brian Granger
39 39 * Enthought, Inc. Some of the code in this file comes from enthought.traits
40 40 and is licensed under the BSD license. Also, many of the ideas also come
41 41 from enthought.traits even though our implementation is very different.
42 42 """
43 43
44 44 #-----------------------------------------------------------------------------
45 45 # Copyright (C) 2008-2011 The IPython Development Team
46 46 #
47 47 # Distributed under the terms of the BSD License. The full license is in
48 48 # the file COPYING, distributed as part of this software.
49 49 #-----------------------------------------------------------------------------
50 50
51 51 #-----------------------------------------------------------------------------
52 52 # Imports
53 53 #-----------------------------------------------------------------------------
54 54
55 55 import contextlib
56 56 import inspect
57 57 import re
58 58 import sys
59 59 import types
60 60 from types import FunctionType
61 61 try:
62 62 from types import ClassType, InstanceType
63 63 ClassTypes = (ClassType, type)
64 64 except:
65 65 ClassTypes = (type,)
66 66
67 67 from .importstring import import_item
68 68 from IPython.utils import py3compat
69 69 from IPython.utils.py3compat import iteritems
70 70 from IPython.testing.skipdoctest import skip_doctest
71 71
72 72 SequenceTypes = (list, tuple, set, frozenset)
73 73
74 74 #-----------------------------------------------------------------------------
75 75 # Basic classes
76 76 #-----------------------------------------------------------------------------
77 77
78 78
79 79 class NoDefaultSpecified ( object ): pass
80 80 NoDefaultSpecified = NoDefaultSpecified()
81 81
82 82
83 83 class Undefined ( object ): pass
84 84 Undefined = Undefined()
85 85
86 86 class TraitError(Exception):
87 87 pass
88 88
89 89 #-----------------------------------------------------------------------------
90 90 # Utilities
91 91 #-----------------------------------------------------------------------------
92 92
93 93
94 94 def class_of ( object ):
95 95 """ Returns a string containing the class name of an object with the
96 96 correct indefinite article ('a' or 'an') preceding it (e.g., 'an Image',
97 97 'a PlotValue').
98 98 """
99 99 if isinstance( object, py3compat.string_types ):
100 100 return add_article( object )
101 101
102 102 return add_article( object.__class__.__name__ )
103 103
104 104
105 105 def add_article ( name ):
106 106 """ Returns a string containing the correct indefinite article ('a' or 'an')
107 107 prefixed to the specified string.
108 108 """
109 109 if name[:1].lower() in 'aeiou':
110 110 return 'an ' + name
111 111
112 112 return 'a ' + name
113 113
114 114
115 115 def repr_type(obj):
116 116 """ Return a string representation of a value and its type for readable
117 117 error messages.
118 118 """
119 119 the_type = type(obj)
120 120 if (not py3compat.PY3) and the_type is InstanceType:
121 121 # Old-style class.
122 122 the_type = obj.__class__
123 123 msg = '%r %r' % (obj, the_type)
124 124 return msg
125 125
126 126
127 127 def is_trait(t):
128 128 """ Returns whether the given value is an instance or subclass of TraitType.
129 129 """
130 130 return (isinstance(t, TraitType) or
131 131 (isinstance(t, type) and issubclass(t, TraitType)))
132 132
133 133
134 134 def parse_notifier_name(name):
135 135 """Convert the name argument to a list of names.
136 136
137 137 Examples
138 138 --------
139 139
140 140 >>> parse_notifier_name('a')
141 141 ['a']
142 142 >>> parse_notifier_name(['a','b'])
143 143 ['a', 'b']
144 144 >>> parse_notifier_name(None)
145 145 ['anytrait']
146 146 """
147 147 if isinstance(name, str):
148 148 return [name]
149 149 elif name is None:
150 150 return ['anytrait']
151 151 elif isinstance(name, (list, tuple)):
152 152 for n in name:
153 153 assert isinstance(n, str), "names must be strings"
154 154 return name
155 155
156 156
157 157 class _SimpleTest:
158 158 def __init__ ( self, value ): self.value = value
159 159 def __call__ ( self, test ):
160 160 return test == self.value
161 161 def __repr__(self):
162 162 return "<SimpleTest(%r)" % self.value
163 163 def __str__(self):
164 164 return self.__repr__()
165 165
166 166
167 167 def getmembers(object, predicate=None):
168 168 """A safe version of inspect.getmembers that handles missing attributes.
169 169
170 170 This is useful when there are descriptor based attributes that for
171 171 some reason raise AttributeError even though they exist. This happens
172 172 in zope.inteface with the __provides__ attribute.
173 173 """
174 174 results = []
175 175 for key in dir(object):
176 176 try:
177 177 value = getattr(object, key)
178 178 except AttributeError:
179 179 pass
180 180 else:
181 181 if not predicate or predicate(value):
182 182 results.append((key, value))
183 183 results.sort()
184 184 return results
185 185
186 186 @skip_doctest
187 class bind(object):
188 """Bind traits from different objects together so they remain in sync.
187 class link(object):
188 """Link traits from different objects together so they remain in sync.
189 189
190 190 Parameters
191 191 ----------
192 192 obj : pairs of objects/attributes
193 193
194 194 Examples
195 195 --------
196 196
197 >>> c = bind((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
197 >>> c = link((obj1, 'value'), (obj2, 'value'), (obj3, 'value'))
198 198 >>> obj1.value = 5 # updates other objects as well
199 199 """
200 200 updating = False
201 201 def __init__(self, *args):
202 202 if len(args) < 2:
203 203 raise TypeError('At least two traitlets must be provided.')
204 204
205 205 self.objects = {}
206 206 initial = getattr(args[0][0], args[0][1])
207 207 for obj,attr in args:
208 208 if getattr(obj, attr) != initial:
209 209 setattr(obj, attr, initial)
210 210
211 211 callback = self._make_closure(obj,attr)
212 212 obj.on_trait_change(callback, attr)
213 213 self.objects[(obj,attr)] = callback
214 214
215 215 @contextlib.contextmanager
216 216 def _busy_updating(self):
217 217 self.updating = True
218 218 try:
219 219 yield
220 220 finally:
221 221 self.updating = False
222 222
223 223 def _make_closure(self, sending_obj, sending_attr):
224 224 def update(name, old, new):
225 225 self._update(sending_obj, sending_attr, new)
226 226 return update
227 227
228 228 def _update(self, sending_obj, sending_attr, new):
229 229 if self.updating:
230 230 return
231 231 with self._busy_updating():
232 232 for obj,attr in self.objects.keys():
233 233 if obj is not sending_obj or attr != sending_attr:
234 234 setattr(obj, attr, new)
235 235
236 def unbind(self):
236 def unlink(self):
237 237 for key, callback in self.objects.items():
238 238 (obj,attr) = key
239 239 obj.on_trait_change(callback, attr, remove=True)
240 240
241 241 #-----------------------------------------------------------------------------
242 242 # Base TraitType for all traits
243 243 #-----------------------------------------------------------------------------
244 244
245 245
246 246 class TraitType(object):
247 247 """A base class for all trait descriptors.
248 248
249 249 Notes
250 250 -----
251 251 Our implementation of traits is based on Python's descriptor
252 252 prototol. This class is the base class for all such descriptors. The
253 253 only magic we use is a custom metaclass for the main :class:`HasTraits`
254 254 class that does the following:
255 255
256 256 1. Sets the :attr:`name` attribute of every :class:`TraitType`
257 257 instance in the class dict to the name of the attribute.
258 258 2. Sets the :attr:`this_class` attribute of every :class:`TraitType`
259 259 instance in the class dict to the *class* that declared the trait.
260 260 This is used by the :class:`This` trait to allow subclasses to
261 261 accept superclasses for :class:`This` values.
262 262 """
263 263
264 264
265 265 metadata = {}
266 266 default_value = Undefined
267 267 info_text = 'any value'
268 268
269 269 def __init__(self, default_value=NoDefaultSpecified, **metadata):
270 270 """Create a TraitType.
271 271 """
272 272 if default_value is not NoDefaultSpecified:
273 273 self.default_value = default_value
274 274
275 275 if len(metadata) > 0:
276 276 if len(self.metadata) > 0:
277 277 self._metadata = self.metadata.copy()
278 278 self._metadata.update(metadata)
279 279 else:
280 280 self._metadata = metadata
281 281 else:
282 282 self._metadata = self.metadata
283 283
284 284 self.init()
285 285
286 286 def init(self):
287 287 pass
288 288
289 289 def get_default_value(self):
290 290 """Create a new instance of the default value."""
291 291 return self.default_value
292 292
293 293 def instance_init(self, obj):
294 294 """This is called by :meth:`HasTraits.__new__` to finish init'ing.
295 295
296 296 Some stages of initialization must be delayed until the parent
297 297 :class:`HasTraits` instance has been created. This method is
298 298 called in :meth:`HasTraits.__new__` after the instance has been
299 299 created.
300 300
301 301 This method trigger the creation and validation of default values
302 302 and also things like the resolution of str given class names in
303 303 :class:`Type` and :class`Instance`.
304 304
305 305 Parameters
306 306 ----------
307 307 obj : :class:`HasTraits` instance
308 308 The parent :class:`HasTraits` instance that has just been
309 309 created.
310 310 """
311 311 self.set_default_value(obj)
312 312
313 313 def set_default_value(self, obj):
314 314 """Set the default value on a per instance basis.
315 315
316 316 This method is called by :meth:`instance_init` to create and
317 317 validate the default value. The creation and validation of
318 318 default values must be delayed until the parent :class:`HasTraits`
319 319 class has been instantiated.
320 320 """
321 321 # Check for a deferred initializer defined in the same class as the
322 322 # trait declaration or above.
323 323 mro = type(obj).mro()
324 324 meth_name = '_%s_default' % self.name
325 325 for cls in mro[:mro.index(self.this_class)+1]:
326 326 if meth_name in cls.__dict__:
327 327 break
328 328 else:
329 329 # We didn't find one. Do static initialization.
330 330 dv = self.get_default_value()
331 331 newdv = self._validate(obj, dv)
332 332 obj._trait_values[self.name] = newdv
333 333 return
334 334 # Complete the dynamic initialization.
335 335 obj._trait_dyn_inits[self.name] = cls.__dict__[meth_name]
336 336
337 337 def __get__(self, obj, cls=None):
338 338 """Get the value of the trait by self.name for the instance.
339 339
340 340 Default values are instantiated when :meth:`HasTraits.__new__`
341 341 is called. Thus by the time this method gets called either the
342 342 default value or a user defined value (they called :meth:`__set__`)
343 343 is in the :class:`HasTraits` instance.
344 344 """
345 345 if obj is None:
346 346 return self
347 347 else:
348 348 try:
349 349 value = obj._trait_values[self.name]
350 350 except KeyError:
351 351 # Check for a dynamic initializer.
352 352 if self.name in obj._trait_dyn_inits:
353 353 value = obj._trait_dyn_inits[self.name](obj)
354 354 # FIXME: Do we really validate here?
355 355 value = self._validate(obj, value)
356 356 obj._trait_values[self.name] = value
357 357 return value
358 358 else:
359 359 raise TraitError('Unexpected error in TraitType: '
360 360 'both default value and dynamic initializer are '
361 361 'absent.')
362 362 except Exception:
363 363 # HasTraits should call set_default_value to populate
364 364 # this. So this should never be reached.
365 365 raise TraitError('Unexpected error in TraitType: '
366 366 'default value not set properly')
367 367 else:
368 368 return value
369 369
370 370 def __set__(self, obj, value):
371 371 new_value = self._validate(obj, value)
372 372 old_value = self.__get__(obj)
373 373 obj._trait_values[self.name] = new_value
374 374 if old_value != new_value:
375 375 obj._notify_trait(self.name, old_value, new_value)
376 376
377 377 def _validate(self, obj, value):
378 378 if hasattr(self, 'validate'):
379 379 return self.validate(obj, value)
380 380 elif hasattr(self, 'is_valid_for'):
381 381 valid = self.is_valid_for(value)
382 382 if valid:
383 383 return value
384 384 else:
385 385 raise TraitError('invalid value for type: %r' % value)
386 386 elif hasattr(self, 'value_for'):
387 387 return self.value_for(value)
388 388 else:
389 389 return value
390 390
391 391 def info(self):
392 392 return self.info_text
393 393
394 394 def error(self, obj, value):
395 395 if obj is not None:
396 396 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
397 397 % (self.name, class_of(obj),
398 398 self.info(), repr_type(value))
399 399 else:
400 400 e = "The '%s' trait must be %s, but a value of %r was specified." \
401 401 % (self.name, self.info(), repr_type(value))
402 402 raise TraitError(e)
403 403
404 404 def get_metadata(self, key):
405 405 return getattr(self, '_metadata', {}).get(key, None)
406 406
407 407 def set_metadata(self, key, value):
408 408 getattr(self, '_metadata', {})[key] = value
409 409
410 410
411 411 #-----------------------------------------------------------------------------
412 412 # The HasTraits implementation
413 413 #-----------------------------------------------------------------------------
414 414
415 415
416 416 class MetaHasTraits(type):
417 417 """A metaclass for HasTraits.
418 418
419 419 This metaclass makes sure that any TraitType class attributes are
420 420 instantiated and sets their name attribute.
421 421 """
422 422
423 423 def __new__(mcls, name, bases, classdict):
424 424 """Create the HasTraits class.
425 425
426 426 This instantiates all TraitTypes in the class dict and sets their
427 427 :attr:`name` attribute.
428 428 """
429 429 # print "MetaHasTraitlets (mcls, name): ", mcls, name
430 430 # print "MetaHasTraitlets (bases): ", bases
431 431 # print "MetaHasTraitlets (classdict): ", classdict
432 432 for k,v in iteritems(classdict):
433 433 if isinstance(v, TraitType):
434 434 v.name = k
435 435 elif inspect.isclass(v):
436 436 if issubclass(v, TraitType):
437 437 vinst = v()
438 438 vinst.name = k
439 439 classdict[k] = vinst
440 440 return super(MetaHasTraits, mcls).__new__(mcls, name, bases, classdict)
441 441
442 442 def __init__(cls, name, bases, classdict):
443 443 """Finish initializing the HasTraits class.
444 444
445 445 This sets the :attr:`this_class` attribute of each TraitType in the
446 446 class dict to the newly created class ``cls``.
447 447 """
448 448 for k, v in iteritems(classdict):
449 449 if isinstance(v, TraitType):
450 450 v.this_class = cls
451 451 super(MetaHasTraits, cls).__init__(name, bases, classdict)
452 452
453 453 class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)):
454 454
455 455 def __new__(cls, *args, **kw):
456 456 # This is needed because in Python 2.6 object.__new__ only accepts
457 457 # the cls argument.
458 458 new_meth = super(HasTraits, cls).__new__
459 459 if new_meth is object.__new__:
460 460 inst = new_meth(cls)
461 461 else:
462 462 inst = new_meth(cls, **kw)
463 463 inst._trait_values = {}
464 464 inst._trait_notifiers = {}
465 465 inst._trait_dyn_inits = {}
466 466 # Here we tell all the TraitType instances to set their default
467 467 # values on the instance.
468 468 for key in dir(cls):
469 469 # Some descriptors raise AttributeError like zope.interface's
470 470 # __provides__ attributes even though they exist. This causes
471 471 # AttributeErrors even though they are listed in dir(cls).
472 472 try:
473 473 value = getattr(cls, key)
474 474 except AttributeError:
475 475 pass
476 476 else:
477 477 if isinstance(value, TraitType):
478 478 value.instance_init(inst)
479 479
480 480 return inst
481 481
482 482 def __init__(self, *args, **kw):
483 483 # Allow trait values to be set using keyword arguments.
484 484 # We need to use setattr for this to trigger validation and
485 485 # notifications.
486 486 for key, value in iteritems(kw):
487 487 setattr(self, key, value)
488 488
489 489 def _notify_trait(self, name, old_value, new_value):
490 490
491 491 # First dynamic ones
492 492 callables = []
493 493 callables.extend(self._trait_notifiers.get(name,[]))
494 494 callables.extend(self._trait_notifiers.get('anytrait',[]))
495 495
496 496 # Now static ones
497 497 try:
498 498 cb = getattr(self, '_%s_changed' % name)
499 499 except:
500 500 pass
501 501 else:
502 502 callables.append(cb)
503 503
504 504 # Call them all now
505 505 for c in callables:
506 506 # Traits catches and logs errors here. I allow them to raise
507 507 if callable(c):
508 508 argspec = inspect.getargspec(c)
509 509 nargs = len(argspec[0])
510 510 # Bound methods have an additional 'self' argument
511 511 # I don't know how to treat unbound methods, but they
512 512 # can't really be used for callbacks.
513 513 if isinstance(c, types.MethodType):
514 514 offset = -1
515 515 else:
516 516 offset = 0
517 517 if nargs + offset == 0:
518 518 c()
519 519 elif nargs + offset == 1:
520 520 c(name)
521 521 elif nargs + offset == 2:
522 522 c(name, new_value)
523 523 elif nargs + offset == 3:
524 524 c(name, old_value, new_value)
525 525 else:
526 526 raise TraitError('a trait changed callback '
527 527 'must have 0-3 arguments.')
528 528 else:
529 529 raise TraitError('a trait changed callback '
530 530 'must be callable.')
531 531
532 532
533 533 def _add_notifiers(self, handler, name):
534 534 if name not in self._trait_notifiers:
535 535 nlist = []
536 536 self._trait_notifiers[name] = nlist
537 537 else:
538 538 nlist = self._trait_notifiers[name]
539 539 if handler not in nlist:
540 540 nlist.append(handler)
541 541
542 542 def _remove_notifiers(self, handler, name):
543 543 if name in self._trait_notifiers:
544 544 nlist = self._trait_notifiers[name]
545 545 try:
546 546 index = nlist.index(handler)
547 547 except ValueError:
548 548 pass
549 549 else:
550 550 del nlist[index]
551 551
552 552 def on_trait_change(self, handler, name=None, remove=False):
553 553 """Setup a handler to be called when a trait changes.
554 554
555 555 This is used to setup dynamic notifications of trait changes.
556 556
557 557 Static handlers can be created by creating methods on a HasTraits
558 558 subclass with the naming convention '_[traitname]_changed'. Thus,
559 559 to create static handler for the trait 'a', create the method
560 560 _a_changed(self, name, old, new) (fewer arguments can be used, see
561 561 below).
562 562
563 563 Parameters
564 564 ----------
565 565 handler : callable
566 566 A callable that is called when a trait changes. Its
567 567 signature can be handler(), handler(name), handler(name, new)
568 568 or handler(name, old, new).
569 569 name : list, str, None
570 570 If None, the handler will apply to all traits. If a list
571 571 of str, handler will apply to all names in the list. If a
572 572 str, the handler will apply just to that name.
573 573 remove : bool
574 574 If False (the default), then install the handler. If True
575 575 then unintall it.
576 576 """
577 577 if remove:
578 578 names = parse_notifier_name(name)
579 579 for n in names:
580 580 self._remove_notifiers(handler, n)
581 581 else:
582 582 names = parse_notifier_name(name)
583 583 for n in names:
584 584 self._add_notifiers(handler, n)
585 585
586 586 @classmethod
587 587 def class_trait_names(cls, **metadata):
588 588 """Get a list of all the names of this classes traits.
589 589
590 590 This method is just like the :meth:`trait_names` method, but is unbound.
591 591 """
592 592 return cls.class_traits(**metadata).keys()
593 593
594 594 @classmethod
595 595 def class_traits(cls, **metadata):
596 596 """Get a list of all the traits of this class.
597 597
598 598 This method is just like the :meth:`traits` method, but is unbound.
599 599
600 600 The TraitTypes returned don't know anything about the values
601 601 that the various HasTrait's instances are holding.
602 602
603 603 This follows the same algorithm as traits does and does not allow
604 604 for any simple way of specifying merely that a metadata name
605 605 exists, but has any value. This is because get_metadata returns
606 606 None if a metadata key doesn't exist.
607 607 """
608 608 traits = dict([memb for memb in getmembers(cls) if \
609 609 isinstance(memb[1], TraitType)])
610 610
611 611 if len(metadata) == 0:
612 612 return traits
613 613
614 614 for meta_name, meta_eval in metadata.items():
615 615 if type(meta_eval) is not FunctionType:
616 616 metadata[meta_name] = _SimpleTest(meta_eval)
617 617
618 618 result = {}
619 619 for name, trait in traits.items():
620 620 for meta_name, meta_eval in metadata.items():
621 621 if not meta_eval(trait.get_metadata(meta_name)):
622 622 break
623 623 else:
624 624 result[name] = trait
625 625
626 626 return result
627 627
628 628 def trait_names(self, **metadata):
629 629 """Get a list of all the names of this classes traits."""
630 630 return self.traits(**metadata).keys()
631 631
632 632 def traits(self, **metadata):
633 633 """Get a list of all the traits of this class.
634 634
635 635 The TraitTypes returned don't know anything about the values
636 636 that the various HasTrait's instances are holding.
637 637
638 638 This follows the same algorithm as traits does and does not allow
639 639 for any simple way of specifying merely that a metadata name
640 640 exists, but has any value. This is because get_metadata returns
641 641 None if a metadata key doesn't exist.
642 642 """
643 643 traits = dict([memb for memb in getmembers(self.__class__) if \
644 644 isinstance(memb[1], TraitType)])
645 645
646 646 if len(metadata) == 0:
647 647 return traits
648 648
649 649 for meta_name, meta_eval in metadata.items():
650 650 if type(meta_eval) is not FunctionType:
651 651 metadata[meta_name] = _SimpleTest(meta_eval)
652 652
653 653 result = {}
654 654 for name, trait in traits.items():
655 655 for meta_name, meta_eval in metadata.items():
656 656 if not meta_eval(trait.get_metadata(meta_name)):
657 657 break
658 658 else:
659 659 result[name] = trait
660 660
661 661 return result
662 662
663 663 def trait_metadata(self, traitname, key):
664 664 """Get metadata values for trait by key."""
665 665 try:
666 666 trait = getattr(self.__class__, traitname)
667 667 except AttributeError:
668 668 raise TraitError("Class %s does not have a trait named %s" %
669 669 (self.__class__.__name__, traitname))
670 670 else:
671 671 return trait.get_metadata(key)
672 672
673 673 #-----------------------------------------------------------------------------
674 674 # Actual TraitTypes implementations/subclasses
675 675 #-----------------------------------------------------------------------------
676 676
677 677 #-----------------------------------------------------------------------------
678 678 # TraitTypes subclasses for handling classes and instances of classes
679 679 #-----------------------------------------------------------------------------
680 680
681 681
682 682 class ClassBasedTraitType(TraitType):
683 683 """A trait with error reporting for Type, Instance and This."""
684 684
685 685 def error(self, obj, value):
686 686 kind = type(value)
687 687 if (not py3compat.PY3) and kind is InstanceType:
688 688 msg = 'class %s' % value.__class__.__name__
689 689 else:
690 690 msg = '%s (i.e. %s)' % ( str( kind )[1:-1], repr( value ) )
691 691
692 692 if obj is not None:
693 693 e = "The '%s' trait of %s instance must be %s, but a value of %s was specified." \
694 694 % (self.name, class_of(obj),
695 695 self.info(), msg)
696 696 else:
697 697 e = "The '%s' trait must be %s, but a value of %r was specified." \
698 698 % (self.name, self.info(), msg)
699 699
700 700 raise TraitError(e)
701 701
702 702
703 703 class Type(ClassBasedTraitType):
704 704 """A trait whose value must be a subclass of a specified class."""
705 705
706 706 def __init__ (self, default_value=None, klass=None, allow_none=True, **metadata ):
707 707 """Construct a Type trait
708 708
709 709 A Type trait specifies that its values must be subclasses of
710 710 a particular class.
711 711
712 712 If only ``default_value`` is given, it is used for the ``klass`` as
713 713 well.
714 714
715 715 Parameters
716 716 ----------
717 717 default_value : class, str or None
718 718 The default value must be a subclass of klass. If an str,
719 719 the str must be a fully specified class name, like 'foo.bar.Bah'.
720 720 The string is resolved into real class, when the parent
721 721 :class:`HasTraits` class is instantiated.
722 722 klass : class, str, None
723 723 Values of this trait must be a subclass of klass. The klass
724 724 may be specified in a string like: 'foo.bar.MyClass'.
725 725 The string is resolved into real class, when the parent
726 726 :class:`HasTraits` class is instantiated.
727 727 allow_none : boolean
728 728 Indicates whether None is allowed as an assignable value. Even if
729 729 ``False``, the default value may be ``None``.
730 730 """
731 731 if default_value is None:
732 732 if klass is None:
733 733 klass = object
734 734 elif klass is None:
735 735 klass = default_value
736 736
737 737 if not (inspect.isclass(klass) or isinstance(klass, py3compat.string_types)):
738 738 raise TraitError("A Type trait must specify a class.")
739 739
740 740 self.klass = klass
741 741 self._allow_none = allow_none
742 742
743 743 super(Type, self).__init__(default_value, **metadata)
744 744
745 745 def validate(self, obj, value):
746 746 """Validates that the value is a valid object instance."""
747 747 try:
748 748 if issubclass(value, self.klass):
749 749 return value
750 750 except:
751 751 if (value is None) and (self._allow_none):
752 752 return value
753 753
754 754 self.error(obj, value)
755 755
756 756 def info(self):
757 757 """ Returns a description of the trait."""
758 758 if isinstance(self.klass, py3compat.string_types):
759 759 klass = self.klass
760 760 else:
761 761 klass = self.klass.__name__
762 762 result = 'a subclass of ' + klass
763 763 if self._allow_none:
764 764 return result + ' or None'
765 765 return result
766 766
767 767 def instance_init(self, obj):
768 768 self._resolve_classes()
769 769 super(Type, self).instance_init(obj)
770 770
771 771 def _resolve_classes(self):
772 772 if isinstance(self.klass, py3compat.string_types):
773 773 self.klass = import_item(self.klass)
774 774 if isinstance(self.default_value, py3compat.string_types):
775 775 self.default_value = import_item(self.default_value)
776 776
777 777 def get_default_value(self):
778 778 return self.default_value
779 779
780 780
781 781 class DefaultValueGenerator(object):
782 782 """A class for generating new default value instances."""
783 783
784 784 def __init__(self, *args, **kw):
785 785 self.args = args
786 786 self.kw = kw
787 787
788 788 def generate(self, klass):
789 789 return klass(*self.args, **self.kw)
790 790
791 791
792 792 class Instance(ClassBasedTraitType):
793 793 """A trait whose value must be an instance of a specified class.
794 794
795 795 The value can also be an instance of a subclass of the specified class.
796 796 """
797 797
798 798 def __init__(self, klass=None, args=None, kw=None,
799 799 allow_none=True, **metadata ):
800 800 """Construct an Instance trait.
801 801
802 802 This trait allows values that are instances of a particular
803 803 class or its sublclasses. Our implementation is quite different
804 804 from that of enthough.traits as we don't allow instances to be used
805 805 for klass and we handle the ``args`` and ``kw`` arguments differently.
806 806
807 807 Parameters
808 808 ----------
809 809 klass : class, str
810 810 The class that forms the basis for the trait. Class names
811 811 can also be specified as strings, like 'foo.bar.Bar'.
812 812 args : tuple
813 813 Positional arguments for generating the default value.
814 814 kw : dict
815 815 Keyword arguments for generating the default value.
816 816 allow_none : bool
817 817 Indicates whether None is allowed as a value.
818 818
819 819 Notes
820 820 -----
821 821 If both ``args`` and ``kw`` are None, then the default value is None.
822 822 If ``args`` is a tuple and ``kw`` is a dict, then the default is
823 823 created as ``klass(*args, **kw)``. If either ``args`` or ``kw`` is
824 824 not (but not both), None is replace by ``()`` or ``{}``.
825 825 """
826 826
827 827 self._allow_none = allow_none
828 828
829 829 if (klass is None) or (not (inspect.isclass(klass) or isinstance(klass, py3compat.string_types))):
830 830 raise TraitError('The klass argument must be a class'
831 831 ' you gave: %r' % klass)
832 832 self.klass = klass
833 833
834 834 # self.klass is a class, so handle default_value
835 835 if args is None and kw is None:
836 836 default_value = None
837 837 else:
838 838 if args is None:
839 839 # kw is not None
840 840 args = ()
841 841 elif kw is None:
842 842 # args is not None
843 843 kw = {}
844 844
845 845 if not isinstance(kw, dict):
846 846 raise TraitError("The 'kw' argument must be a dict or None.")
847 847 if not isinstance(args, tuple):
848 848 raise TraitError("The 'args' argument must be a tuple or None.")
849 849
850 850 default_value = DefaultValueGenerator(*args, **kw)
851 851
852 852 super(Instance, self).__init__(default_value, **metadata)
853 853
854 854 def validate(self, obj, value):
855 855 if value is None:
856 856 if self._allow_none:
857 857 return value
858 858 self.error(obj, value)
859 859
860 860 if isinstance(value, self.klass):
861 861 return value
862 862 else:
863 863 self.error(obj, value)
864 864
865 865 def info(self):
866 866 if isinstance(self.klass, py3compat.string_types):
867 867 klass = self.klass
868 868 else:
869 869 klass = self.klass.__name__
870 870 result = class_of(klass)
871 871 if self._allow_none:
872 872 return result + ' or None'
873 873
874 874 return result
875 875
876 876 def instance_init(self, obj):
877 877 self._resolve_classes()
878 878 super(Instance, self).instance_init(obj)
879 879
880 880 def _resolve_classes(self):
881 881 if isinstance(self.klass, py3compat.string_types):
882 882 self.klass = import_item(self.klass)
883 883
884 884 def get_default_value(self):
885 885 """Instantiate a default value instance.
886 886
887 887 This is called when the containing HasTraits classes'
888 888 :meth:`__new__` method is called to ensure that a unique instance
889 889 is created for each HasTraits instance.
890 890 """
891 891 dv = self.default_value
892 892 if isinstance(dv, DefaultValueGenerator):
893 893 return dv.generate(self.klass)
894 894 else:
895 895 return dv
896 896
897 897
898 898 class This(ClassBasedTraitType):
899 899 """A trait for instances of the class containing this trait.
900 900
901 901 Because how how and when class bodies are executed, the ``This``
902 902 trait can only have a default value of None. This, and because we
903 903 always validate default values, ``allow_none`` is *always* true.
904 904 """
905 905
906 906 info_text = 'an instance of the same type as the receiver or None'
907 907
908 908 def __init__(self, **metadata):
909 909 super(This, self).__init__(None, **metadata)
910 910
911 911 def validate(self, obj, value):
912 912 # What if value is a superclass of obj.__class__? This is
913 913 # complicated if it was the superclass that defined the This
914 914 # trait.
915 915 if isinstance(value, self.this_class) or (value is None):
916 916 return value
917 917 else:
918 918 self.error(obj, value)
919 919
920 920
921 921 #-----------------------------------------------------------------------------
922 922 # Basic TraitTypes implementations/subclasses
923 923 #-----------------------------------------------------------------------------
924 924
925 925
926 926 class Any(TraitType):
927 927 default_value = None
928 928 info_text = 'any value'
929 929
930 930
931 931 class Int(TraitType):
932 932 """An int trait."""
933 933
934 934 default_value = 0
935 935 info_text = 'an int'
936 936
937 937 def validate(self, obj, value):
938 938 if isinstance(value, int):
939 939 return value
940 940 self.error(obj, value)
941 941
942 942 class CInt(Int):
943 943 """A casting version of the int trait."""
944 944
945 945 def validate(self, obj, value):
946 946 try:
947 947 return int(value)
948 948 except:
949 949 self.error(obj, value)
950 950
951 951 if py3compat.PY3:
952 952 Long, CLong = Int, CInt
953 953 Integer = Int
954 954 else:
955 955 class Long(TraitType):
956 956 """A long integer trait."""
957 957
958 958 default_value = 0
959 959 info_text = 'a long'
960 960
961 961 def validate(self, obj, value):
962 962 if isinstance(value, long):
963 963 return value
964 964 if isinstance(value, int):
965 965 return long(value)
966 966 self.error(obj, value)
967 967
968 968
969 969 class CLong(Long):
970 970 """A casting version of the long integer trait."""
971 971
972 972 def validate(self, obj, value):
973 973 try:
974 974 return long(value)
975 975 except:
976 976 self.error(obj, value)
977 977
978 978 class Integer(TraitType):
979 979 """An integer trait.
980 980
981 981 Longs that are unnecessary (<= sys.maxint) are cast to ints."""
982 982
983 983 default_value = 0
984 984 info_text = 'an integer'
985 985
986 986 def validate(self, obj, value):
987 987 if isinstance(value, int):
988 988 return value
989 989 if isinstance(value, long):
990 990 # downcast longs that fit in int:
991 991 # note that int(n > sys.maxint) returns a long, so
992 992 # we don't need a condition on this cast
993 993 return int(value)
994 994 if sys.platform == "cli":
995 995 from System import Int64
996 996 if isinstance(value, Int64):
997 997 return int(value)
998 998 self.error(obj, value)
999 999
1000 1000
1001 1001 class Float(TraitType):
1002 1002 """A float trait."""
1003 1003
1004 1004 default_value = 0.0
1005 1005 info_text = 'a float'
1006 1006
1007 1007 def validate(self, obj, value):
1008 1008 if isinstance(value, float):
1009 1009 return value
1010 1010 if isinstance(value, int):
1011 1011 return float(value)
1012 1012 self.error(obj, value)
1013 1013
1014 1014
1015 1015 class CFloat(Float):
1016 1016 """A casting version of the float trait."""
1017 1017
1018 1018 def validate(self, obj, value):
1019 1019 try:
1020 1020 return float(value)
1021 1021 except:
1022 1022 self.error(obj, value)
1023 1023
1024 1024 class Complex(TraitType):
1025 1025 """A trait for complex numbers."""
1026 1026
1027 1027 default_value = 0.0 + 0.0j
1028 1028 info_text = 'a complex number'
1029 1029
1030 1030 def validate(self, obj, value):
1031 1031 if isinstance(value, complex):
1032 1032 return value
1033 1033 if isinstance(value, (float, int)):
1034 1034 return complex(value)
1035 1035 self.error(obj, value)
1036 1036
1037 1037
1038 1038 class CComplex(Complex):
1039 1039 """A casting version of the complex number trait."""
1040 1040
1041 1041 def validate (self, obj, value):
1042 1042 try:
1043 1043 return complex(value)
1044 1044 except:
1045 1045 self.error(obj, value)
1046 1046
1047 1047 # We should always be explicit about whether we're using bytes or unicode, both
1048 1048 # for Python 3 conversion and for reliable unicode behaviour on Python 2. So
1049 1049 # we don't have a Str type.
1050 1050 class Bytes(TraitType):
1051 1051 """A trait for byte strings."""
1052 1052
1053 1053 default_value = b''
1054 1054 info_text = 'a bytes object'
1055 1055
1056 1056 def validate(self, obj, value):
1057 1057 if isinstance(value, bytes):
1058 1058 return value
1059 1059 self.error(obj, value)
1060 1060
1061 1061
1062 1062 class CBytes(Bytes):
1063 1063 """A casting version of the byte string trait."""
1064 1064
1065 1065 def validate(self, obj, value):
1066 1066 try:
1067 1067 return bytes(value)
1068 1068 except:
1069 1069 self.error(obj, value)
1070 1070
1071 1071
1072 1072 class Unicode(TraitType):
1073 1073 """A trait for unicode strings."""
1074 1074
1075 1075 default_value = u''
1076 1076 info_text = 'a unicode string'
1077 1077
1078 1078 def validate(self, obj, value):
1079 1079 if isinstance(value, py3compat.unicode_type):
1080 1080 return value
1081 1081 if isinstance(value, bytes):
1082 1082 try:
1083 1083 return value.decode('ascii', 'strict')
1084 1084 except UnicodeDecodeError:
1085 1085 msg = "Could not decode {!r} for unicode trait '{}' of {} instance."
1086 1086 raise TraitError(msg.format(value, self.name, class_of(obj)))
1087 1087 self.error(obj, value)
1088 1088
1089 1089
1090 1090 class CUnicode(Unicode):
1091 1091 """A casting version of the unicode trait."""
1092 1092
1093 1093 def validate(self, obj, value):
1094 1094 try:
1095 1095 return py3compat.unicode_type(value)
1096 1096 except:
1097 1097 self.error(obj, value)
1098 1098
1099 1099
1100 1100 class ObjectName(TraitType):
1101 1101 """A string holding a valid object name in this version of Python.
1102 1102
1103 1103 This does not check that the name exists in any scope."""
1104 1104 info_text = "a valid object identifier in Python"
1105 1105
1106 1106 if py3compat.PY3:
1107 1107 # Python 3:
1108 1108 coerce_str = staticmethod(lambda _,s: s)
1109 1109
1110 1110 else:
1111 1111 # Python 2:
1112 1112 def coerce_str(self, obj, value):
1113 1113 "In Python 2, coerce ascii-only unicode to str"
1114 1114 if isinstance(value, unicode):
1115 1115 try:
1116 1116 return str(value)
1117 1117 except UnicodeEncodeError:
1118 1118 self.error(obj, value)
1119 1119 return value
1120 1120
1121 1121 def validate(self, obj, value):
1122 1122 value = self.coerce_str(obj, value)
1123 1123
1124 1124 if isinstance(value, str) and py3compat.isidentifier(value):
1125 1125 return value
1126 1126 self.error(obj, value)
1127 1127
1128 1128 class DottedObjectName(ObjectName):
1129 1129 """A string holding a valid dotted object name in Python, such as A.b3._c"""
1130 1130 def validate(self, obj, value):
1131 1131 value = self.coerce_str(obj, value)
1132 1132
1133 1133 if isinstance(value, str) and py3compat.isidentifier(value, dotted=True):
1134 1134 return value
1135 1135 self.error(obj, value)
1136 1136
1137 1137
1138 1138 class Bool(TraitType):
1139 1139 """A boolean (True, False) trait."""
1140 1140
1141 1141 default_value = False
1142 1142 info_text = 'a boolean'
1143 1143
1144 1144 def validate(self, obj, value):
1145 1145 if isinstance(value, bool):
1146 1146 return value
1147 1147 self.error(obj, value)
1148 1148
1149 1149
1150 1150 class CBool(Bool):
1151 1151 """A casting version of the boolean trait."""
1152 1152
1153 1153 def validate(self, obj, value):
1154 1154 try:
1155 1155 return bool(value)
1156 1156 except:
1157 1157 self.error(obj, value)
1158 1158
1159 1159
1160 1160 class Enum(TraitType):
1161 1161 """An enum that whose value must be in a given sequence."""
1162 1162
1163 1163 def __init__(self, values, default_value=None, allow_none=True, **metadata):
1164 1164 self.values = values
1165 1165 self._allow_none = allow_none
1166 1166 super(Enum, self).__init__(default_value, **metadata)
1167 1167
1168 1168 def validate(self, obj, value):
1169 1169 if value is None:
1170 1170 if self._allow_none:
1171 1171 return value
1172 1172
1173 1173 if value in self.values:
1174 1174 return value
1175 1175 self.error(obj, value)
1176 1176
1177 1177 def info(self):
1178 1178 """ Returns a description of the trait."""
1179 1179 result = 'any of ' + repr(self.values)
1180 1180 if self._allow_none:
1181 1181 return result + ' or None'
1182 1182 return result
1183 1183
1184 1184 class CaselessStrEnum(Enum):
1185 1185 """An enum of strings that are caseless in validate."""
1186 1186
1187 1187 def validate(self, obj, value):
1188 1188 if value is None:
1189 1189 if self._allow_none:
1190 1190 return value
1191 1191
1192 1192 if not isinstance(value, py3compat.string_types):
1193 1193 self.error(obj, value)
1194 1194
1195 1195 for v in self.values:
1196 1196 if v.lower() == value.lower():
1197 1197 return v
1198 1198 self.error(obj, value)
1199 1199
1200 1200 class Container(Instance):
1201 1201 """An instance of a container (list, set, etc.)
1202 1202
1203 1203 To be subclassed by overriding klass.
1204 1204 """
1205 1205 klass = None
1206 1206 _valid_defaults = SequenceTypes
1207 1207 _trait = None
1208 1208
1209 1209 def __init__(self, trait=None, default_value=None, allow_none=True,
1210 1210 **metadata):
1211 1211 """Create a container trait type from a list, set, or tuple.
1212 1212
1213 1213 The default value is created by doing ``List(default_value)``,
1214 1214 which creates a copy of the ``default_value``.
1215 1215
1216 1216 ``trait`` can be specified, which restricts the type of elements
1217 1217 in the container to that TraitType.
1218 1218
1219 1219 If only one arg is given and it is not a Trait, it is taken as
1220 1220 ``default_value``:
1221 1221
1222 1222 ``c = List([1,2,3])``
1223 1223
1224 1224 Parameters
1225 1225 ----------
1226 1226
1227 1227 trait : TraitType [ optional ]
1228 1228 the type for restricting the contents of the Container. If unspecified,
1229 1229 types are not checked.
1230 1230
1231 1231 default_value : SequenceType [ optional ]
1232 1232 The default value for the Trait. Must be list/tuple/set, and
1233 1233 will be cast to the container type.
1234 1234
1235 1235 allow_none : Bool [ default True ]
1236 1236 Whether to allow the value to be None
1237 1237
1238 1238 **metadata : any
1239 1239 further keys for extensions to the Trait (e.g. config)
1240 1240
1241 1241 """
1242 1242 # allow List([values]):
1243 1243 if default_value is None and not is_trait(trait):
1244 1244 default_value = trait
1245 1245 trait = None
1246 1246
1247 1247 if default_value is None:
1248 1248 args = ()
1249 1249 elif isinstance(default_value, self._valid_defaults):
1250 1250 args = (default_value,)
1251 1251 else:
1252 1252 raise TypeError('default value of %s was %s' %(self.__class__.__name__, default_value))
1253 1253
1254 1254 if is_trait(trait):
1255 1255 self._trait = trait() if isinstance(trait, type) else trait
1256 1256 self._trait.name = 'element'
1257 1257 elif trait is not None:
1258 1258 raise TypeError("`trait` must be a Trait or None, got %s"%repr_type(trait))
1259 1259
1260 1260 super(Container,self).__init__(klass=self.klass, args=args,
1261 1261 allow_none=allow_none, **metadata)
1262 1262
1263 1263 def element_error(self, obj, element, validator):
1264 1264 e = "Element of the '%s' trait of %s instance must be %s, but a value of %s was specified." \
1265 1265 % (self.name, class_of(obj), validator.info(), repr_type(element))
1266 1266 raise TraitError(e)
1267 1267
1268 1268 def validate(self, obj, value):
1269 1269 value = super(Container, self).validate(obj, value)
1270 1270 if value is None:
1271 1271 return value
1272 1272
1273 1273 value = self.validate_elements(obj, value)
1274 1274
1275 1275 return value
1276 1276
1277 1277 def validate_elements(self, obj, value):
1278 1278 validated = []
1279 1279 if self._trait is None or isinstance(self._trait, Any):
1280 1280 return value
1281 1281 for v in value:
1282 1282 try:
1283 1283 v = self._trait.validate(obj, v)
1284 1284 except TraitError:
1285 1285 self.element_error(obj, v, self._trait)
1286 1286 else:
1287 1287 validated.append(v)
1288 1288 return self.klass(validated)
1289 1289
1290 1290
1291 1291 class List(Container):
1292 1292 """An instance of a Python list."""
1293 1293 klass = list
1294 1294
1295 1295 def __init__(self, trait=None, default_value=None, minlen=0, maxlen=sys.maxsize,
1296 1296 allow_none=True, **metadata):
1297 1297 """Create a List trait type from a list, set, or tuple.
1298 1298
1299 1299 The default value is created by doing ``List(default_value)``,
1300 1300 which creates a copy of the ``default_value``.
1301 1301
1302 1302 ``trait`` can be specified, which restricts the type of elements
1303 1303 in the container to that TraitType.
1304 1304
1305 1305 If only one arg is given and it is not a Trait, it is taken as
1306 1306 ``default_value``:
1307 1307
1308 1308 ``c = List([1,2,3])``
1309 1309
1310 1310 Parameters
1311 1311 ----------
1312 1312
1313 1313 trait : TraitType [ optional ]
1314 1314 the type for restricting the contents of the Container. If unspecified,
1315 1315 types are not checked.
1316 1316
1317 1317 default_value : SequenceType [ optional ]
1318 1318 The default value for the Trait. Must be list/tuple/set, and
1319 1319 will be cast to the container type.
1320 1320
1321 1321 minlen : Int [ default 0 ]
1322 1322 The minimum length of the input list
1323 1323
1324 1324 maxlen : Int [ default sys.maxsize ]
1325 1325 The maximum length of the input list
1326 1326
1327 1327 allow_none : Bool [ default True ]
1328 1328 Whether to allow the value to be None
1329 1329
1330 1330 **metadata : any
1331 1331 further keys for extensions to the Trait (e.g. config)
1332 1332
1333 1333 """
1334 1334 self._minlen = minlen
1335 1335 self._maxlen = maxlen
1336 1336 super(List, self).__init__(trait=trait, default_value=default_value,
1337 1337 allow_none=allow_none, **metadata)
1338 1338
1339 1339 def length_error(self, obj, value):
1340 1340 e = "The '%s' trait of %s instance must be of length %i <= L <= %i, but a value of %s was specified." \
1341 1341 % (self.name, class_of(obj), self._minlen, self._maxlen, value)
1342 1342 raise TraitError(e)
1343 1343
1344 1344 def validate_elements(self, obj, value):
1345 1345 length = len(value)
1346 1346 if length < self._minlen or length > self._maxlen:
1347 1347 self.length_error(obj, value)
1348 1348
1349 1349 return super(List, self).validate_elements(obj, value)
1350 1350
1351 1351
1352 1352 class Set(Container):
1353 1353 """An instance of a Python set."""
1354 1354 klass = set
1355 1355
1356 1356 class Tuple(Container):
1357 1357 """An instance of a Python tuple."""
1358 1358 klass = tuple
1359 1359
1360 1360 def __init__(self, *traits, **metadata):
1361 1361 """Tuple(*traits, default_value=None, allow_none=True, **medatata)
1362 1362
1363 1363 Create a tuple from a list, set, or tuple.
1364 1364
1365 1365 Create a fixed-type tuple with Traits:
1366 1366
1367 1367 ``t = Tuple(Int, Str, CStr)``
1368 1368
1369 1369 would be length 3, with Int,Str,CStr for each element.
1370 1370
1371 1371 If only one arg is given and it is not a Trait, it is taken as
1372 1372 default_value:
1373 1373
1374 1374 ``t = Tuple((1,2,3))``
1375 1375
1376 1376 Otherwise, ``default_value`` *must* be specified by keyword.
1377 1377
1378 1378 Parameters
1379 1379 ----------
1380 1380
1381 1381 *traits : TraitTypes [ optional ]
1382 1382 the tsype for restricting the contents of the Tuple. If unspecified,
1383 1383 types are not checked. If specified, then each positional argument
1384 1384 corresponds to an element of the tuple. Tuples defined with traits
1385 1385 are of fixed length.
1386 1386
1387 1387 default_value : SequenceType [ optional ]
1388 1388 The default value for the Tuple. Must be list/tuple/set, and
1389 1389 will be cast to a tuple. If `traits` are specified, the
1390 1390 `default_value` must conform to the shape and type they specify.
1391 1391
1392 1392 allow_none : Bool [ default True ]
1393 1393 Whether to allow the value to be None
1394 1394
1395 1395 **metadata : any
1396 1396 further keys for extensions to the Trait (e.g. config)
1397 1397
1398 1398 """
1399 1399 default_value = metadata.pop('default_value', None)
1400 1400 allow_none = metadata.pop('allow_none', True)
1401 1401
1402 1402 # allow Tuple((values,)):
1403 1403 if len(traits) == 1 and default_value is None and not is_trait(traits[0]):
1404 1404 default_value = traits[0]
1405 1405 traits = ()
1406 1406
1407 1407 if default_value is None:
1408 1408 args = ()
1409 1409 elif isinstance(default_value, self._valid_defaults):
1410 1410 args = (default_value,)
1411 1411 else:
1412 1412 raise TypeError('default value of %s was %s' %(self.__class__.__name__, default_value))
1413 1413
1414 1414 self._traits = []
1415 1415 for trait in traits:
1416 1416 t = trait() if isinstance(trait, type) else trait
1417 1417 t.name = 'element'
1418 1418 self._traits.append(t)
1419 1419
1420 1420 if self._traits and default_value is None:
1421 1421 # don't allow default to be an empty container if length is specified
1422 1422 args = None
1423 1423 super(Container,self).__init__(klass=self.klass, args=args,
1424 1424 allow_none=allow_none, **metadata)
1425 1425
1426 1426 def validate_elements(self, obj, value):
1427 1427 if not self._traits:
1428 1428 # nothing to validate
1429 1429 return value
1430 1430 if len(value) != len(self._traits):
1431 1431 e = "The '%s' trait of %s instance requires %i elements, but a value of %s was specified." \
1432 1432 % (self.name, class_of(obj), len(self._traits), repr_type(value))
1433 1433 raise TraitError(e)
1434 1434
1435 1435 validated = []
1436 1436 for t,v in zip(self._traits, value):
1437 1437 try:
1438 1438 v = t.validate(obj, v)
1439 1439 except TraitError:
1440 1440 self.element_error(obj, v, t)
1441 1441 else:
1442 1442 validated.append(v)
1443 1443 return tuple(validated)
1444 1444
1445 1445
1446 1446 class Dict(Instance):
1447 1447 """An instance of a Python dict."""
1448 1448
1449 1449 def __init__(self, default_value=None, allow_none=True, **metadata):
1450 1450 """Create a dict trait type from a dict.
1451 1451
1452 1452 The default value is created by doing ``dict(default_value)``,
1453 1453 which creates a copy of the ``default_value``.
1454 1454 """
1455 1455 if default_value is None:
1456 1456 args = ((),)
1457 1457 elif isinstance(default_value, dict):
1458 1458 args = (default_value,)
1459 1459 elif isinstance(default_value, SequenceTypes):
1460 1460 args = (default_value,)
1461 1461 else:
1462 1462 raise TypeError('default value of Dict was %s' % default_value)
1463 1463
1464 1464 super(Dict,self).__init__(klass=dict, args=args,
1465 1465 allow_none=allow_none, **metadata)
1466 1466
1467 1467 class TCPAddress(TraitType):
1468 1468 """A trait for an (ip, port) tuple.
1469 1469
1470 1470 This allows for both IPv4 IP addresses as well as hostnames.
1471 1471 """
1472 1472
1473 1473 default_value = ('127.0.0.1', 0)
1474 1474 info_text = 'an (ip, port) tuple'
1475 1475
1476 1476 def validate(self, obj, value):
1477 1477 if isinstance(value, tuple):
1478 1478 if len(value) == 2:
1479 1479 if isinstance(value[0], py3compat.string_types) and isinstance(value[1], int):
1480 1480 port = value[1]
1481 1481 if port >= 0 and port <= 65535:
1482 1482 return value
1483 1483 self.error(obj, value)
1484 1484
1485 1485 class CRegExp(TraitType):
1486 1486 """A casting compiled regular expression trait.
1487 1487
1488 1488 Accepts both strings and compiled regular expressions. The resulting
1489 1489 attribute will be a compiled regular expression."""
1490 1490
1491 1491 info_text = 'a regular expression'
1492 1492
1493 1493 def validate(self, obj, value):
1494 1494 try:
1495 1495 return re.compile(value)
1496 1496 except:
1497 1497 self.error(obj, value)
@@ -1,83 +1,77 b''
1 1 """A script for watching all traffic on the IOPub channel (stdout/stderr/pyerr) of engines.
2 2
3 3 This connects to the default cluster, or you can pass the path to your ipcontroller-client.json
4 4
5 5 Try running this script, and then running a few jobs that print (and call sys.stdout.flush),
6 6 and you will see the print statements as they arrive, notably not waiting for the results
7 7 to finish.
8 8
9 9 You can use the zeromq SUBSCRIBE mechanism to only receive information from specific engines,
10 10 and easily filter by message type.
11 11
12 12 Authors
13 13 -------
14 14 * MinRK
15 15 """
16 16
17 import os
18 17 import sys
19 18 import json
20 19 import zmq
21 20
22 21 from IPython.kernel.zmq.session import Session
23 from IPython.parallel.util import disambiguate_url
24 22 from IPython.utils.py3compat import str_to_bytes
25 23 from IPython.utils.path import get_security_file
26 24
27 25 def main(connection_file):
28 26 """watch iopub channel, and print messages"""
29 27
30 28 ctx = zmq.Context.instance()
31 29
32 30 with open(connection_file) as f:
33 31 cfg = json.loads(f.read())
34 32
35 location = cfg['location']
36 reg_url = cfg['url']
37 session = Session(key=str_to_bytes(cfg['exec_key']))
33 reg_url = cfg['interface']
34 iopub_port = cfg['iopub']
35 iopub_url = "%s:%s"%(reg_url, iopub_port)
38 36
39 query = ctx.socket(zmq.DEALER)
40 query.connect(disambiguate_url(cfg['url'], location))
41 session.send(query, "connection_request")
42 idents,msg = session.recv(query, mode=0)
43 c = msg['content']
44 iopub_url = disambiguate_url(c['iopub'], location)
37 session = Session(key=str_to_bytes(cfg['key']))
45 38 sub = ctx.socket(zmq.SUB)
39
46 40 # This will subscribe to all messages:
47 41 sub.setsockopt(zmq.SUBSCRIBE, b'')
48 42 # replace with b'' with b'engine.1.stdout' to subscribe only to engine 1's stdout
49 43 # 0MQ subscriptions are simple 'foo*' matches, so 'engine.1.' subscribes
50 44 # to everything from engine 1, but there is no way to subscribe to
51 45 # just stdout from everyone.
52 46 # multiple calls to subscribe will add subscriptions, e.g. to subscribe to
53 47 # engine 1's stderr and engine 2's stdout:
54 48 # sub.setsockopt(zmq.SUBSCRIBE, b'engine.1.stderr')
55 49 # sub.setsockopt(zmq.SUBSCRIBE, b'engine.2.stdout')
56 50 sub.connect(iopub_url)
57 51 while True:
58 52 try:
59 53 idents,msg = session.recv(sub, mode=0)
60 54 except KeyboardInterrupt:
61 55 return
62 56 # ident always length 1 here
63 57 topic = idents[0]
64 58 if msg['msg_type'] == 'stream':
65 59 # stdout/stderr
66 60 # stream names are in msg['content']['name'], if you want to handle
67 61 # them differently
68 62 print("%s: %s" % (topic, msg['content']['data']))
69 63 elif msg['msg_type'] == 'pyerr':
70 64 # Python traceback
71 65 c = msg['content']
72 66 print(topic + ':')
73 67 for line in c['traceback']:
74 68 # indent lines
75 69 print(' ' + line)
76 70
77 71 if __name__ == '__main__':
78 72 if len(sys.argv) > 1:
79 73 cf = sys.argv[1]
80 74 else:
81 75 # This gets the security file for the default profile:
82 76 cf = get_security_file('ipcontroller-client.json')
83 77 main(cf)
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now