From b8e379565a758b8323f33f5ad93795ce290d0517 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:44:12 +0000 Subject: [PATCH] deploy: 0951105146b22cd66b0e703478fdbf73a6509448 --- .nojekyll | 0 .../figure-html/cell-35-output-1.png | Bin 0 -> 33507 bytes .../figure-html/cell-36-output-1.png | Bin 0 -> 2837 bytes .../figure-html/cell-38-output-1.png | Bin 0 -> 49078 bytes .../figure-html/cell-73-output-1.png | Bin 0 -> 137479 bytes CNAME | 1 + basics.html | 3442 +++++++++++++++++ dispatch.html | 1266 ++++++ docments.html | 1036 +++++ foundation.html | 1522 ++++++++ images/att_00000.png | Bin 0 -> 35850 bytes images/att_00005.png | Bin 0 -> 8156 bytes images/att_00006.png | Bin 0 -> 8133 bytes images/att_00007.png | Bin 0 -> 9873 bytes index.html | 712 ++++ meta.html | 1292 +++++++ net.html | 1042 +++++ parallel.html | 976 +++++ py2pyi.html | 1123 ++++++ robots.txt | 1 + script.html | 999 +++++ search.json | 632 +++ site_libs/bootstrap/bootstrap-icons.css | 2078 ++++++++++ site_libs/bootstrap/bootstrap-icons.woff | Bin 0 -> 176200 bytes site_libs/bootstrap/bootstrap.min.css | 12 + site_libs/bootstrap/bootstrap.min.js | 7 + site_libs/clipboard/clipboard.min.js | 7 + site_libs/quarto-html/anchor.min.js | 9 + site_libs/quarto-html/popper.min.js | 6 + .../quarto-syntax-highlighting.css | 205 + site_libs/quarto-html/quarto.js | 908 +++++ site_libs/quarto-html/tippy.css | 1 + site_libs/quarto-html/tippy.umd.min.js | 2 + site_libs/quarto-nav/headroom.min.js | 7 + site_libs/quarto-nav/quarto-nav.js | 325 ++ site_libs/quarto-search/autocomplete.umd.js | 3 + site_libs/quarto-search/fuse.min.js | 9 + site_libs/quarto-search/quarto-search.js | 1290 ++++++ sitemap.xml | 71 + style.html | 876 +++++ styles.css | 18 + test.html | 1062 +++++ tour.html | 936 +++++ transform.html | 1433 +++++++ xdg.html | 850 ++++ xml.html | 962 +++++ xtras.html | 2245 +++++++++++ 47 files changed, 27366 insertions(+) create mode 100644 .nojekyll create mode 100644 00_test_files/figure-html/cell-35-output-1.png create mode 100644 00_test_files/figure-html/cell-36-output-1.png create mode 100644 00_test_files/figure-html/cell-38-output-1.png create mode 100644 05_transform_files/figure-html/cell-73-output-1.png create mode 100644 CNAME create mode 100644 basics.html create mode 100644 dispatch.html create mode 100644 docments.html create mode 100644 foundation.html create mode 100644 images/att_00000.png create mode 100644 images/att_00005.png create mode 100644 images/att_00006.png create mode 100644 images/att_00007.png create mode 100644 index.html create mode 100644 meta.html create mode 100644 net.html create mode 100644 parallel.html create mode 100644 py2pyi.html create mode 100644 robots.txt create mode 100644 script.html create mode 100644 search.json create mode 100644 site_libs/bootstrap/bootstrap-icons.css create mode 100644 site_libs/bootstrap/bootstrap-icons.woff create mode 100644 site_libs/bootstrap/bootstrap.min.css create mode 100644 site_libs/bootstrap/bootstrap.min.js create mode 100644 site_libs/clipboard/clipboard.min.js create mode 100644 site_libs/quarto-html/anchor.min.js create mode 100644 site_libs/quarto-html/popper.min.js create mode 100644 site_libs/quarto-html/quarto-syntax-highlighting.css create mode 100644 site_libs/quarto-html/quarto.js create mode 100644 site_libs/quarto-html/tippy.css create mode 100644 site_libs/quarto-html/tippy.umd.min.js create mode 100644 site_libs/quarto-nav/headroom.min.js create mode 100644 site_libs/quarto-nav/quarto-nav.js create mode 100644 site_libs/quarto-search/autocomplete.umd.js create mode 100644 site_libs/quarto-search/fuse.min.js create mode 100644 site_libs/quarto-search/quarto-search.js create mode 100644 sitemap.xml create mode 100644 style.html create mode 100644 styles.css create mode 100644 test.html create mode 100644 tour.html create mode 100644 transform.html create mode 100644 xdg.html create mode 100644 xml.html create mode 100644 xtras.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/00_test_files/figure-html/cell-35-output-1.png b/00_test_files/figure-html/cell-35-output-1.png new file mode 100644 index 0000000000000000000000000000000000000000..7b80ee81fc4070bf694ffc1a480f9ebf924c184b GIT binary patch literal 33507 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 Eg4Agq?f?J) literal 0 HcmV?d00001 diff --git a/00_test_files/figure-html/cell-36-output-1.png b/00_test_files/figure-html/cell-36-output-1.png new file mode 100644 index 0000000000000000000000000000000000000000..4ddbcd3eb80b6feb5ed8858efb02a38dbcc4aad2 GIT binary patch literal 2837 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 literal 0 HcmV?d00001 diff --git a/00_test_files/figure-html/cell-38-output-1.png b/00_test_files/figure-html/cell-38-output-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e59c91c32d22ab32dd470ebca63f98c6bb8726 GIT binary patch literal 49078 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 TI7S0T$TO{>`b;&ZgD`{+9*Gb3 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 LNkvXXu0mjfWz?cc literal 0 HcmV?d00001 diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..d9bb41c6 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +fastcore.fast.ai diff --git a/basics.html b/basics.html new file mode 100644 index 00000000..79ad56a9 --- /dev/null +++ b/basics.html @@ -0,0 +1,3442 @@ + + + + + + + + + + +Basic functionality – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Basic functionality

+
+ +
+
+ Basic functionality used in the fastai library +
+
+ + +
+ + + + +
+ + + +
+ + + +
+

Basics

+
+

source

+
+

ifnone

+
+
 ifnone (a, b)
+
+

b if a is None else a

+

Since b if a is None else a is such a common pattern, we wrap it in a function. However, be careful, because python will evaluate both a and b when calling ifnone (which it doesn’t do if using the if version directly).

+
+
test_eq(ifnone(None,1), 1)
+test_eq(ifnone(2   ,1), 2)
+
+
+

source

+
+
+

maybe_attr

+
+
 maybe_attr (o, attr)
+
+

getattr(o,attr,o)

+

Return the attribute attr for object o. If the attribute doesn’t exist, then return the object o instead.

+
+
class myobj: myattr='foo'
+
+test_eq(maybe_attr(myobj, 'myattr'), 'foo')
+test_eq(maybe_attr(myobj, 'another_attr'), myobj)
+
+
+

source

+
+
+

basic_repr

+
+
 basic_repr (flds=None)
+
+

Minimal __repr__

+

In types which provide rich display functionality in Jupyter, their __repr__ is also called in order to provide a fallback text representation. Unfortunately, this includes a memory address which changes on every invocation, making it non-deterministic. This causes diffs to get messy and creates conflicts in git. To fix this, put __repr__=basic_repr() inside your class.

+
+
class SomeClass: __repr__=basic_repr()
+repr(SomeClass())
+
+
'<__main__.SomeClass>'
+
+
+

If you pass a list of attributes (flds) of an object, then this will generate a string with the name of each attribute and its corresponding value. The format of this string is key=value, where key is the name of the attribute, and value is the value of the attribute. For each value, attempt to use the __name__ attribute, otherwise fall back to using the value’s __repr__ when constructing the string.

+
+
class SomeClass:
+    a=1
+    b='foo'
+    __repr__=basic_repr('a,b')
+    __name__='some-class'
+
+repr(SomeClass())
+
+
"__main__.SomeClass(a=1, b='foo')"
+
+
+
+
class AnotherClass:
+    c=SomeClass()
+    d='bar'
+    __repr__=basic_repr(['c', 'd'])
+
+repr(AnotherClass())
+
+
"__main__.AnotherClass(c=__main__.SomeClass(a=1, b='foo'), d='bar')"
+
+
+
+

source

+
+
+

is_array

+
+
 is_array (x)
+
+

True if x supports __array__ or iloc

+
+
is_array(np.array(1)),is_array([1])
+
+
(True, False)
+
+
+
+

source

+
+
+

listify

+
+
 listify (o=None, *rest, use_list=False, match=None)
+
+

Convert o to a list

+

Conversion is designed to “do what you mean”, e.g:

+
+
test_eq(listify('hi'), ['hi'])
+test_eq(listify(b'hi'), [b'hi'])
+test_eq(listify(array(1)), [array(1)])
+test_eq(listify(1), [1])
+test_eq(listify([1,2]), [1,2])
+test_eq(listify(range(3)), [0,1,2])
+test_eq(listify(None), [])
+test_eq(listify(1,2), [1,2])
+
+
+
arr = np.arange(9).reshape(3,3)
+listify(arr)
+
+
[array([[0, 1, 2],
+        [3, 4, 5],
+        [6, 7, 8]])]
+
+
+
+
listify(array([1,2]))
+
+
[array([1, 2])]
+
+
+

Generators are turned into lists too:

+
+
gen = (o for o in range(3))
+test_eq(listify(gen), [0,1,2])
+
+

Use match to provide a length to match:

+
+
test_eq(listify(1,match=3), [1,1,1])
+
+

If match is a sequence, it’s length is used:

+
+
test_eq(listify(1,match=range(3)), [1,1,1])
+
+

If the listified item is not of length 1, it must be the same length as match:

+
+
test_eq(listify([1,1,1],match=3), [1,1,1])
+test_fail(lambda: listify([1,1],match=3))
+
+
+

source

+
+
+

tuplify

+
+
 tuplify (o, use_list=False, match=None)
+
+

Make o a tuple

+
+
test_eq(tuplify(None),())
+test_eq(tuplify([1,2,3]),(1,2,3))
+test_eq(tuplify(1,match=[1,2,3]),(1,1,1))
+
+
+

source

+
+
+

true

+
+
 true (x)
+
+

Test whether x is truthy; collections with >0 elements are considered True

+
+
[(o,true(o)) for o in
+ (array(0),array(1),array([0]),array([0,1]),1,0,'',None)]
+
+
[(array(0), False),
+ (array(1), True),
+ (array([0]), True),
+ (array([0, 1]), True),
+ (1, True),
+ (0, False),
+ ('', False),
+ (None, False)]
+
+
+
+

source

+
+
+

NullType

+
+
 NullType ()
+
+

An object that is False and can be called, chained, and indexed

+
+
bool(null.hi().there[3])
+
+
False
+
+
+
+

source

+
+
+

tonull

+
+
 tonull (x)
+
+

Convert None to null

+
+
bool(tonull(None).hi().there[3])
+
+
False
+
+
+
+

source

+
+
+

get_class

+
+
 get_class (nm, *fld_names, sup=None, doc=None, funcs=None, anno=None,
+            **flds)
+
+

Dynamically create a class, optionally inheriting from sup, containing fld_names

+
+
_t = get_class('_t', 'a', b=2, anno={'b':int})
+t = _t()
+test_eq(t.a, None)
+test_eq(t.b, 2)
+t = _t(1, b=3)
+test_eq(t.a, 1)
+test_eq(t.b, 3)
+t = _t(1, 3)
+test_eq(t.a, 1)
+test_eq(t.b, 3)
+test_eq(t, pickle.loads(pickle.dumps(t)))
+test_eq(_t.__annotations__, {'b':int, 'a':typing.Any})
+repr(t)
+
+
'__main__._t(a=1, b=3)'
+
+
+

Most often you’ll want to call mk_class, since it adds the class to your module. See mk_class for more details and examples of use (which also apply to get_class).

+
+

source

+
+
+

mk_class

+
+
 mk_class (nm, *fld_names, sup=None, doc=None, funcs=None, mod=None,
+           anno=None, **flds)
+
+

Create a class using get_class and add to the caller’s module

+

Any kwargs will be added as class attributes, and sup is an optional (tuple of) base classes.

+
+
mk_class('_t', a=1, sup=dict)
+t = _t()
+test_eq(t.a, 1)
+assert(isinstance(t,dict))
+
+

A __init__ is provided that sets attrs for any kwargs, and for any args (matching by position to fields), along with a __repr__ which prints all attrs. The docstring is set to doc. You can pass funcs which will be added as attrs with the function names.

+
+
def foo(self): return 1
+mk_class('_t', 'a', sup=dict, doc='test doc', funcs=foo)
+
+t = _t(3, b=2)
+test_eq(t.a, 3)
+test_eq(t.b, 2)
+test_eq(t.foo(), 1)
+test_eq(t.__doc__, 'test doc')
+t
+
+
{}
+
+
+
+

source

+
+
+

wrap_class

+
+
 wrap_class (nm, *fld_names, sup=None, doc=None, funcs=None, **flds)
+
+

Decorator: makes function a method of a new class nm passing parameters to mk_class

+
+
@wrap_class('_t', a=2)
+def bar(self,x): return x+1
+
+t = _t()
+test_eq(t.a, 2)
+test_eq(t.bar(3), 4)
+
+
+

source

+
+

ignore_exceptions

+
+
 ignore_exceptions ()
+
+

Context manager to ignore exceptions

+
+
with ignore_exceptions(): 
+    # Exception will be ignored
+    raise Exception
+
+
+

source

+
+
+
+

exec_local

+
+
 exec_local (code, var_name)
+
+

Call exec on code and return the var var_name

+
+
test_eq(exec_local("a=1", "a"), 1)
+
+
+

source

+
+
+

risinstance

+
+
 risinstance (types, obj=None)
+
+

Curried isinstance but with args reversed

+
+
assert risinstance(int, 1)
+assert not risinstance(str, 0)
+assert risinstance(int)(1)
+
+

types can also be strings:

+
+
assert risinstance(('str','int'), 'a')
+assert risinstance('str', 'a')
+assert not risinstance('int', 'a')
+
+
+

source

+
+
+

ver2tuple

+
+
 ver2tuple (v:str)
+
+
+
test_eq(ver2tuple('3.8.1'), (3,8,1))
+test_eq(ver2tuple('3.1'), (3,1,0))
+test_eq(ver2tuple('3.'), (3,0,0))
+test_eq(ver2tuple('3'), (3,0,0))
+
+
+
+
+

NoOp

+

These are used when you need a pass-through function.

+
+
+

noop

+
+
 noop (x=None, *args, **kwargs)
+
+

Do nothing

+
+
noop()
+test_eq(noop(1),1)
+
+
+
+
+

noops

+
+
 noops (x=None, *args, **kwargs)
+
+

Do nothing (method)

+
+
class _t: foo=noops
+test_eq(_t().foo(1),1)
+
+
+
+
+

Infinite Lists

+

These lists are useful for things like padding an array or adding index column(s) to arrays.

+

Inf defines the following properties:

+
    +
  • count: itertools.count()
  • +
  • zeros: itertools.cycle([0])
  • +
  • ones : itertools.cycle([1])
  • +
  • nones: itertools.cycle([None])
  • +
+
+
test_eq([o for i,o in zip(range(5), Inf.count)],
+        [0, 1, 2, 3, 4])
+
+test_eq([o for i,o in zip(range(5), Inf.zeros)],
+        [0]*5)
+
+test_eq([o for i,o in zip(range(5), Inf.ones)],
+        [1]*5)
+
+test_eq([o for i,o in zip(range(5), Inf.nones)],
+        [None]*5)
+
+
+
+

Operator Functions

+
+

source

+
+

in_

+
+
 in_ (x, a)
+
+

True if x in a

+
+
# test if element is in another
+assert in_('c', ('b', 'c', 'a'))
+assert in_(4, [2,3,4,5])
+assert in_('t', 'fastai')
+test_fail(in_('h', 'fastai'))
+
+# use in_ as a partial
+assert in_('fastai')('t')
+assert in_([2,3,4,5])(4)
+test_fail(in_('fastai')('h'))
+
+

In addition to in_, the following functions are provided matching the behavior of the equivalent versions in operator: lt gt le ge eq ne add sub mul truediv is_ is_not mod.

+
+
lt(3,5),gt(3,5),is_(None,None),in_(0,[1,2]),mod(3,2)
+
+
(True, False, True, False, 1)
+
+
+

Similarly to _in, they also have additional functionality: if you only pass one param, they return a partial function that passes that param as the second positional parameter.

+
+
lt(5)(3),gt(5)(3),is_(None)(None),in_([1,2])(0),mod(2)(3)
+
+
(True, False, True, False, 1)
+
+
+
+

source

+
+
+

ret_true

+
+
 ret_true (*args, **kwargs)
+
+

Predicate: always True

+
+
assert ret_true(1,2,3)
+assert ret_true(False)
+
+
+

source

+
+
+

ret_false

+
+
 ret_false (*args, **kwargs)
+
+

Predicate: always False

+
+

source

+
+
+

stop

+
+
 stop (e=<class 'StopIteration'>)
+
+

Raises exception e (by default StopIteration)

+
+

source

+
+
+

gen

+
+
 gen (func, seq, cond=<function ret_true>)
+
+

Like (func(o) for o in seq if cond(func(o))) but handles StopIteration

+
+
test_eq(gen(noop, Inf.count, lt(5)),
+        range(5))
+test_eq(gen(operator.neg, Inf.count, gt(-5)),
+        [0,-1,-2,-3,-4])
+test_eq(gen(lambda o:o if o<5 else stop(), Inf.count),
+        range(5))
+
+
+

source

+
+
+

chunked

+
+
 chunked (it, chunk_sz=None, drop_last=False, n_chunks=None)
+
+

Return batches from iterator it of size chunk_sz (or return n_chunks total)

+

Note that you must pass either chunk_sz, or n_chunks, but not both.

+
+
t = list(range(10))
+test_eq(chunked(t,3),      [[0,1,2], [3,4,5], [6,7,8], [9]])
+test_eq(chunked(t,3,True), [[0,1,2], [3,4,5], [6,7,8],    ])
+
+t = map(lambda o:stop() if o==6 else o, Inf.count)
+test_eq(chunked(t,3), [[0, 1, 2], [3, 4, 5]])
+t = map(lambda o:stop() if o==7 else o, Inf.count)
+test_eq(chunked(t,3), [[0, 1, 2], [3, 4, 5], [6]])
+
+t = np.arange(10)
+test_eq(chunked(t,3),      [[0,1,2], [3,4,5], [6,7,8], [9]])
+test_eq(chunked(t,3,True), [[0,1,2], [3,4,5], [6,7,8],    ])
+
+test_eq(chunked([], 3),          [])
+test_eq(chunked([], n_chunks=3), [])
+
+
+

source

+
+
+

otherwise

+
+
 otherwise (x, tst, y)
+
+

y if tst(x) else x

+
+
test_eq(otherwise(2+1, gt(3), 4), 3)
+test_eq(otherwise(2+1, gt(2), 4), 4)
+
+
+
+
+

Attribute Helpers

+

These functions reduce boilerplate when setting or manipulating attributes or properties of objects.

+
+

source

+
+

custom_dir

+
+
 custom_dir (c, add)
+
+

Implement custom __dir__, adding add to cls

+

custom_dir allows you extract the __dict__ property of a class and appends the list add to it.

+
+
class _T: 
+    def f(): pass
+
+s = custom_dir(_T(), add=['foo', 'bar'])
+assert {'foo', 'bar', 'f'}.issubset(s)
+
+
+

source

+
+
+

AttrDict

+

dict subclass that also provides access to keys as attrs

+
+
d = AttrDict(a=1,b="two")
+test_eq(d.a, 1)
+test_eq(d['b'], 'two')
+test_eq(d.get('c','nope'), 'nope')
+d.b = 2
+test_eq(d.b, 2)
+test_eq(d['b'], 2)
+d['b'] = 3
+test_eq(d['b'], 3)
+test_eq(d.b, 3)
+assert 'a' in dir(d)
+
+

AttrDict will pretty print in Jupyter Notebooks:

+
+
_test_dict = {'a':1, 'b': {'c':1, 'd':2}, 'c': {'c':1, 'd':2}, 'd': {'c':1, 'd':2},
+              'e': {'c':1, 'd':2}, 'f': {'c':1, 'd':2, 'e': 4, 'f':[1,2,3,4,5]}}
+AttrDict(_test_dict)
+
+
{ 'a': 1,
+  'b': {'c': 1, 'd': 2},
+  'c': {'c': 1, 'd': 2},
+  'd': {'c': 1, 'd': 2},
+  'e': {'c': 1, 'd': 2},
+  'f': {'c': 1, 'd': 2, 'e': 4, 'f': [1, 2, 3, 4, 5]}}
+
+
+
+

source

+
+
+

NS

+

SimpleNamespace subclass that also adds iter and dict support

+

This is very similar to AttrDict, but since it starts with SimpleNamespace, it has some differences in behavior. You can use it just like SimpleNamespace:

+
+
d = NS(**_test_dict)
+d
+
+
namespace(a=1,
+          b={'c': 1, 'd': 2},
+          c={'c': 1, 'd': 2},
+          d={'c': 1, 'd': 2},
+          e={'c': 1, 'd': 2},
+          f={'c': 1, 'd': 2, 'e': 4, 'f': [1, 2, 3, 4, 5]})
+
+
+

…but you can also index it to get/set:

+
+
d['a']
+
+
1
+
+
+

…and iterate t:

+
+
list(d)
+
+
['a', 'b', 'c', 'd', 'e', 'f']
+
+
+
+

source

+
+
+

get_annotations_ex

+
+
 get_annotations_ex (obj, globals=None, locals=None)
+
+

Backport of py3.10 get_annotations that returns globals/locals

+

In Python 3.10 inspect.get_annotations was added. However previous versions of Python are unable to evaluate type annotations correctly if from future import __annotations__ is used. Furthermore, all annotations are evaluated, even if only some subset are needed. get_annotations_ex provides the same functionality as inspect.get_annotations, but works on earlier versions of Python, and returns the globals and locals needed to evaluate types.

+
+

source

+
+
+

eval_type

+
+
 eval_type (t, glb, loc)
+
+

eval a type or collection of types, if needed, for annotations in py3.10+

+

In py3.10, or if from future import __annotations__ is used, a is a str:

+
+
class _T2a: pass
+def func(a: _T2a): pass
+ann,glb,loc = get_annotations_ex(func)
+
+eval_type(ann['a'], glb, loc)
+
+
__main__._T2a
+
+
+

| is supported for defining Union types when using eval_type even for python versions prior to 3.9:

+
+
class _T2b: pass
+def func(a: _T2a|_T2b): pass
+ann,glb,loc = get_annotations_ex(func)
+
+eval_type(ann['a'], glb, loc)
+
+
typing.Union[__main__._T2a, __main__._T2b]
+
+
+
+

source

+
+
+

type_hints

+
+
 type_hints (f)
+
+

Like typing.get_type_hints but returns {} if not allowed type

+

Below is a list of allowed types for type hints in python:

+
+
list(typing._allowed_types)
+
+
[function,
+ builtin_function_or_method,
+ method,
+ module,
+ wrapper_descriptor,
+ method-wrapper,
+ method_descriptor]
+
+
+

For example, type func is allowed so type_hints returns the same value as typing.get_hints:

+
+
def f(a:int)->bool: ... # a function with type hints (allowed)
+exp = {'a':int,'return':bool}
+test_eq(type_hints(f), typing.get_type_hints(f))
+test_eq(type_hints(f), exp)
+
+

However, class is not an allowed type, so type_hints returns {}:

+
+
class _T:
+    def __init__(self, a:int=0)->bool: ...
+assert not type_hints(_T)
+
+
+

source

+
+
+

annotations

+
+
 annotations (o)
+
+

Annotations for o, or type(o)

+

This supports a wider range of situations than type_hints, by checking type() and __init__ for annotations too:

+
+
for o in _T,_T(),_T.__init__,f: test_eq(annotations(o), exp)
+assert not annotations(int)
+assert not annotations(print)
+
+
+

source

+
+
+

anno_ret

+
+
 anno_ret (func)
+
+

Get the return annotation of func

+
+
def f(x) -> float: return x
+test_eq(anno_ret(f), float)
+
+def f(x) -> typing.Tuple[float,float]: return x
+assert anno_ret(f)==typing.Tuple[float,float]
+
+

If your return annotation is None, anno_ret will return NoneType (and not None):

+
+
def f(x) -> None: return x
+
+test_eq(anno_ret(f), NoneType)
+assert anno_ret(f) is not None # returns NoneType instead of None
+
+

If your function does not have a return type, or if you pass in None instead of a function, then anno_ret returns None:

+
+
def f(x): return x
+
+test_eq(anno_ret(f), None)
+test_eq(anno_ret(None), None) # instead of passing in a func, pass in None
+
+
+

source

+
+
+

signature_ex

+
+
 signature_ex (obj, eval_str:bool=False)
+
+

Backport of inspect.signature(..., eval_str=True to <py310

+
+

source

+
+
+

union2tuple

+
+
 union2tuple (t)
+
+
+
test_eq(union2tuple(Union[int,str]), (int,str))
+test_eq(union2tuple(int), int)
+assert union2tuple(Tuple[int,str])==Tuple[int,str]
+test_eq(union2tuple((int,str)), (int,str))
+if UnionType: test_eq(union2tuple(int|str), (int,str))
+
+
+

source

+
+
+

argnames

+
+
 argnames (f, frame=False)
+
+

Names of arguments to function or frame f

+
+
test_eq(argnames(f), ['x'])
+
+
+

source

+
+
+

with_cast

+
+
 with_cast (f)
+
+

Decorator which uses any parameter annotations as preprocessing functions

+
+
@with_cast
+def _f(a, b:Path, c:str='', d=0): return (a,b,c,d)
+
+test_eq(_f(1, '.', 3), (1,Path('.'),'3',0))
+test_eq(_f(1, '.'), (1,Path('.'),'',0))
+
+@with_cast
+def _g(a:int=0)->str: return a
+
+test_eq(_g(4.0), '4')
+test_eq(_g(4.4), '4')
+test_eq(_g(2), '2')
+
+
+

source

+
+
+

store_attr

+
+
 store_attr (names=None, but='', cast=False, store_args=None, **attrs)
+
+

Store params named in comma-separated names from calling context into attrs in self

+

In it’s most basic form, you can use store_attr to shorten code like this:

+
+
class T:
+    def __init__(self, a,b,c): self.a,self.b,self.c = a,b,c
+
+

…to this:

+
+
class T:
+    def __init__(self, a,b,c): store_attr('a,b,c', self)
+
+

This class behaves as if we’d used the first form:

+
+
t = T(1,c=2,b=3)
+assert t.a==1 and t.b==3 and t.c==2
+
+

In addition, it stores the attrs as a dict in __stored_args__, which you can use for display, logging, and so forth.

+
+
test_eq(t.__stored_args__, {'a':1, 'b':3, 'c':2})
+
+

Since you normally want to use the first argument (often called self) for storing attributes, it’s optional:

+
+
class T:
+    def __init__(self, a,b,c:str): store_attr('a,b,c')
+
+t = T(1,c=2,b=3)
+assert t.a==1 and t.b==3 and t.c==2
+
+

With cast=True any parameter annotations will be used as preprocessing functions for the corresponding arguments:

+
+
class T:
+    def __init__(self, a:listify, b, c:str): store_attr('a,b,c', cast=True)
+
+t = T(1,c=2,b=3)
+assert t.a==[1] and t.b==3 and t.c=='2'
+
+

You can inherit from a class using store_attr, and just call it again to add in any new attributes added in the derived class:

+
+
class T2(T):
+    def __init__(self, d, **kwargs):
+        super().__init__(**kwargs)
+        store_attr('d')
+
+t = T2(d=1,a=2,b=3,c=4)
+assert t.a==2 and t.b==3 and t.c==4 and t.d==1
+
+

You can skip passing a list of attrs to store. In this case, all arguments passed to the method are stored:

+
+
class T:
+    def __init__(self, a,b,c): store_attr()
+
+t = T(1,c=2,b=3)
+assert t.a==1 and t.b==3 and t.c==2
+
+
+
class T4(T):
+    def __init__(self, d, **kwargs):
+        super().__init__(**kwargs)
+        store_attr()
+
+t = T4(4, a=1,c=2,b=3)
+assert t.a==1 and t.b==3 and t.c==2 and t.d==4
+
+
+
class T4:
+    def __init__(self, *, a: int, b: float = 1):
+        store_attr()
+        
+t = T4(a=3)
+assert t.a==3 and t.b==1
+t = T4(a=3, b=2)
+assert t.a==3 and t.b==2
+
+

You can skip some attrs by passing but:

+
+
class T:
+    def __init__(self, a,b,c): store_attr(but='a')
+
+t = T(1,c=2,b=3)
+assert t.b==3 and t.c==2
+assert not hasattr(t,'a')
+
+

You can also pass keywords to store_attr, which is identical to setting the attrs directly, but also stores them in __stored_args__.

+
+
class T:
+    def __init__(self): store_attr(a=1)
+
+t = T()
+assert t.a==1
+
+

You can also use store_attr inside functions.

+
+
def create_T(a, b):
+    t = SimpleNamespace()
+    store_attr(self=t)
+    return t
+
+t = create_T(a=1, b=2)
+assert t.a==1 and t.b==2
+
+
+

source

+
+
+

attrdict

+
+
 attrdict (o, *ks, default=None)
+
+

Dict from each k in ks to getattr(o,k)

+
+
class T:
+    def __init__(self, a,b,c): store_attr()
+
+t = T(1,c=2,b=3)
+test_eq(attrdict(t,'b','c'), {'b':3, 'c':2})
+
+
+

source

+
+
+

properties

+
+
 properties (cls, *ps)
+
+

Change attrs in cls with names in ps to properties

+
+
class T:
+    def a(self): return 1
+    def b(self): return 2
+properties(T,'a')
+
+test_eq(T().a,1)
+test_eq(T().b(),2)
+
+
+

source

+
+
+

camel2words

+
+
 camel2words (s, space=' ')
+
+

Convert CamelCase to ‘spaced words’

+
+
test_eq(camel2words('ClassAreCamel'), 'Class Are Camel')
+
+
+

source

+
+
+

camel2snake

+
+
 camel2snake (name)
+
+

Convert CamelCase to snake_case

+
+
test_eq(camel2snake('ClassAreCamel'), 'class_are_camel')
+test_eq(camel2snake('Already_Snake'), 'already__snake')
+
+
+

source

+
+
+

snake2camel

+
+
 snake2camel (s)
+
+

Convert snake_case to CamelCase

+
+
test_eq(snake2camel('a_b_cc'), 'ABCc')
+
+
+

source

+
+
+

class2attr

+
+
 class2attr (cls_name)
+
+

Return the snake-cased name of the class; strip ending cls_name if it exists.

+
+
class Parent:
+    @property
+    def name(self): return class2attr(self, 'Parent')
+
+class ChildOfParent(Parent): pass
+class ParentChildOf(Parent): pass
+
+p = Parent()
+cp = ChildOfParent()
+cp2 = ParentChildOf()
+
+test_eq(p.name, 'parent')
+test_eq(cp.name, 'child_of')
+test_eq(cp2.name, 'parent_child_of')
+
+
+

source

+
+
+

getcallable

+
+
 getcallable (o, attr)
+
+

Calls getattr with a default of noop

+
+
class Math:
+    def addition(self,a,b): return a+b
+
+m = Math()
+
+test_eq(getcallable(m, "addition")(a=1,b=2), 3)
+test_eq(getcallable(m, "subtraction")(a=1,b=2), None)
+
+
+

source

+
+
+

getattrs

+
+
 getattrs (o, *attrs, default=None)
+
+

List of all attrs in o

+
+
from fractions import Fraction
+
+
+
getattrs(Fraction(1,2), 'numerator', 'denominator')
+
+
[1, 2]
+
+
+
+

source

+
+
+

hasattrs

+
+
 hasattrs (o, attrs)
+
+

Test whether o contains all attrs

+
+
assert hasattrs(1,('imag','real'))
+assert not hasattrs(1,('imag','foo'))
+
+
+

source

+
+
+

setattrs

+
+
 setattrs (dest, flds, src)
+
+
+
d = dict(a=1,bb="2",ignore=3)
+o = SimpleNamespace()
+setattrs(o, "a,bb", d)
+test_eq(o.a, 1)
+test_eq(o.bb, "2")
+
+
+
d = SimpleNamespace(a=1,bb="2",ignore=3)
+o = SimpleNamespace()
+setattrs(o, "a,bb", d)
+test_eq(o.a, 1)
+test_eq(o.bb, "2")
+
+
+

source

+
+
+

try_attrs

+
+
 try_attrs (obj, *attrs)
+
+

Return first attr that exists in obj

+
+
test_eq(try_attrs(1, 'real'), 1)
+test_eq(try_attrs(1, 'foobar', 'real'), 1)
+
+
+
+
+

Attribute Delegation

+
+

source

+
+

GetAttrBase

+
+
 GetAttrBase ()
+
+

Basic delegation of __getattr__ and __dir__

+
+

source

+
+

GetAttr

+
+
 GetAttr ()
+
+

Inherit from this to have all attr accesses in self._xtra passed down to self.default

+

Inherit from GetAttr to have attr access passed down to an instance attribute. This makes it easy to create composites that don’t require callers to know about their components. For a more detailed discussion of how this works as well as relevant context, we suggest reading the delegated composition section of this blog article.

+

You can customise the behaviour of GetAttr in subclasses via; - _default - By default, this is set to 'default', so attr access is passed down to self.default - _default can be set to the name of any instance attribute that does not start with dunder __ - _xtra - By default, this is None, so all attr access is passed down - You can limit which attrs get passed down by setting _xtra to a list of attribute names

+

To illuminate the utility of GetAttr, suppose we have the following two classes, _WebPage which is a superclass of _ProductPage, which we wish to compose like so:

+
+
class _WebPage:
+    def __init__(self, title, author="Jeremy"):
+        self.title,self.author = title,author
+
+class _ProductPage:
+    def __init__(self, page, price): self.page,self.price = page,price
+        
+page = _WebPage('Soap', author="Sylvain")
+p = _ProductPage(page, 15.0)
+
+

How do we make it so we can just write p.author, instead of p.page.author to access the author attribute? We can use GetAttr, of course! First, we subclass GetAttr when defining _ProductPage. Next, we set self.default to the object whose attributes we want to be able to access directly, which in this case is the page argument passed on initialization:

+
+
class _ProductPage(GetAttr):
+    def __init__(self, page, price): self.default,self.price = page,price #self.default allows you to access page directly.
+
+p = _ProductPage(page, 15.0)
+
+

Now, we can access the author attribute directly from the instance:

+
+
test_eq(p.author, 'Sylvain')
+
+

If you wish to store the object you are composing in an attribute other than self.default, you can set the class attribute _data as shown below. This is useful in the case where you might have a name collision with self.default:

+
+
class _C(GetAttr):
+    _default = '_data' # use different component name; `self._data` rather than `self.default`
+    def __init__(self,a): self._data = a
+    def foo(self): noop
+
+t = _C('Hi')
+test_eq(t._data, 'Hi') 
+test_fail(lambda: t.default) # we no longer have self.default
+test_eq(t.lower(), 'hi')
+test_eq(t.upper(), 'HI')
+assert 'lower' in dir(t)
+assert 'upper' in dir(t)
+
+

By default, all attributes and methods of the object you are composing are retained. In the below example, we compose a str object with the class _C. This allows us to directly call string methods on instances of class _C, such as str.lower() or str.upper():

+
+
class _C(GetAttr):
+    # allow all attributes and methods to get passed to `self.default` (by leaving _xtra=None)
+    def __init__(self,a): self.default = a
+    def foo(self): noop
+
+t = _C('Hi')
+test_eq(t.lower(), 'hi')
+test_eq(t.upper(), 'HI')
+assert 'lower' in dir(t)
+assert 'upper' in dir(t)
+
+

However, you can choose which attributes or methods to retain by defining a class attribute _xtra, which is a list of allowed attribute and method names to delegate. In the below example, we only delegate the lower method from the composed str object when defining class _C:

+
+
class _C(GetAttr):
+    _xtra = ['lower'] # specify which attributes get passed to `self.default`
+    def __init__(self,a): self.default = a
+    def foo(self): noop
+
+t = _C('Hi')
+test_eq(t.default, 'Hi')
+test_eq(t.lower(), 'hi')
+test_fail(lambda: t.upper()) # upper wasn't in _xtra, so it isn't available to be called
+assert 'lower' in dir(t)
+assert 'upper' not in dir(t)
+
+

You must be careful to properly set an instance attribute in __init__ that corresponds to the class attribute _default. The below example sets the class attribute _default to data, but erroneously fails to define self.data (and instead defines self.default).

+

Failing to properly set instance attributes leads to errors when you try to access methods directly:

+
+
class _C(GetAttr):
+    _default = 'data' # use a bad component name; i.e. self.data does not exist
+    def __init__(self,a): self.default = a
+    def foo(self): noop
+        
+# TODO: should we raise an error when we create a new instance ...
+t = _C('Hi')
+test_eq(t.default, 'Hi')
+# ... or is it enough for all GetAttr features to raise errors
+test_fail(lambda: t.data)
+test_fail(lambda: t.lower())
+test_fail(lambda: t.upper())
+test_fail(lambda: dir(t))
+
+
+

source

+
+
+
+

delegate_attr

+
+
 delegate_attr (k, to)
+
+

Use in __getattr__ to delegate to attr to without inheriting from GetAttr

+

delegate_attr is a functional way to delegate attributes, and is an alternative to GetAttr. We recommend reading the documentation of GetAttr for more details around delegation.

+

You can use achieve delegation when you define __getattr__ by using delegate_attr:

+
+
class _C:
+    def __init__(self, o): self.o = o # self.o corresponds to the `to` argument in delegate_attr.
+    def __getattr__(self, k): return delegate_attr(self, k, to='o')
+    
+
+t = _C('HELLO') # delegates to a string
+test_eq(t.lower(), 'hello')
+
+t = _C(np.array([5,4,3])) # delegates to a numpy array
+test_eq(t.sum(), 12)
+
+t = _C(pd.DataFrame({'a': [1,2], 'b': [3,4]})) # delegates to a pandas.DataFrame
+test_eq(t.b.max(), 4)
+
+
+
+
+

Extensible Types

+

ShowPrint is a base class that defines a show method, which is used primarily for callbacks in fastai that expect this method to be defined.

+

Int, Float, and Str extend int, float and str respectively by adding an additional show method by inheriting from ShowPrint.

+

The code for Int is shown below:

+

Examples:

+
+
Int(0).show()
+Float(2.0).show()
+Str('Hello').show()
+
+
0
+2.0
+Hello
+
+
+
+
+

Collection functions

+

Functions that manipulate popular python collections.

+
+

source

+
+

partition

+
+
 partition (coll, f)
+
+

Partition a collection by a predicate

+
+
ts,fs = partition(range(10), mod(2))
+test_eq(fs, [0,2,4,6,8])
+test_eq(ts, [1,3,5,7,9])
+
+
+

source

+
+
+

flatten

+
+
 flatten (o)
+
+

Concatenate all collections and items as a generator

+
+

source

+
+
+

concat

+
+
 concat (colls)
+
+

Concatenate all collections and items as a list

+
+
concat([(o for o in range(2)),[2,3,4], 5])
+
+
[0, 1, 2, 3, 4, 5]
+
+
+
+
concat([["abc", "xyz"], ["foo", "bar"]])
+
+
['abc', 'xyz', 'foo', 'bar']
+
+
+
+

source

+
+
+

strcat

+
+
 strcat (its, sep:str='')
+
+

Concatenate stringified items its

+
+
test_eq(strcat(['a',2]), 'a2')
+test_eq(strcat(['a',2], ';'), 'a;2')
+
+
+

source

+
+
+

detuplify

+
+
 detuplify (x)
+
+

If x is a tuple with one thing, extract it

+
+
test_eq(detuplify(()),None)
+test_eq(detuplify([1]),1)
+test_eq(detuplify([1,2]), [1,2])
+test_eq(detuplify(np.array([[1,2]])), np.array([[1,2]]))
+
+
+

source

+
+
+

replicate

+
+
 replicate (item, match)
+
+

Create tuple of item copied len(match) times

+
+
t = [1,1]
+test_eq(replicate([1,2], t),([1,2],[1,2]))
+test_eq(replicate(1, t),(1,1))
+
+
+

source

+
+
+

setify

+
+
 setify (o)
+
+

Turn any list like-object into a set.

+
+
# test
+test_eq(setify(None),set())
+test_eq(setify('abc'),{'abc'})
+test_eq(setify([1,2,2]),{1,2})
+test_eq(setify(range(0,3)),{0,1,2})
+test_eq(setify({1,2}),{1,2})
+
+
+

source

+
+
+

merge

+
+
 merge (*ds)
+
+

Merge all dictionaries in ds

+
+
test_eq(merge(), {})
+test_eq(merge(dict(a=1,b=2)), dict(a=1,b=2))
+test_eq(merge(dict(a=1,b=2), dict(b=3,c=4), None), dict(a=1, b=3, c=4))
+
+
+

source

+
+
+

range_of

+
+
 range_of (x)
+
+

All indices of collection x (i.e. list(range(len(x))))

+
+
test_eq(range_of([1,1,1,1]), [0,1,2,3])
+
+
+

source

+
+
+

groupby

+
+
 groupby (x, key, val=<function noop>)
+
+

Like itertools.groupby but doesn’t need to be sorted, and isn’t lazy, plus some extensions

+
+
test_eq(groupby('aa ab bb'.split(), itemgetter(0)), {'a':['aa','ab'], 'b':['bb']})
+
+

Here’s an example of how to invert a grouping, using an int as key (which uses itemgetter; passing a str will use attrgetter), and using a val function:

+
+
d = {0: [1, 3, 7], 2: [3], 3: [5], 4: [8], 5: [4], 7: [5]}
+groupby(((o,k) for k,v in d.items() for o in v), 0, 1)
+
+
{1: [0], 3: [0, 2], 7: [0], 5: [3, 7], 8: [4], 4: [5]}
+
+
+
+

source

+
+
+

last_index

+
+
 last_index (x, o)
+
+

Finds the last index of occurence of x in o (returns -1 if no occurence)

+
+
test_eq(last_index(9, [1, 2, 9, 3, 4, 9, 10]), 5)
+test_eq(last_index(6, [1, 2, 9, 3, 4, 9, 10]), -1)
+
+
+

source

+
+
+

filter_dict

+
+
 filter_dict (d, func)
+
+

Filter a dict using func, applied to keys and values

+
+
letters = {o:chr(o) for o in range(65,73)}
+letters
+
+
{65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H'}
+
+
+
+
filter_dict(letters, lambda k,v: k<67 or v in 'FG')
+
+
{65: 'A', 66: 'B', 70: 'F', 71: 'G'}
+
+
+
+

source

+
+
+

filter_keys

+
+
 filter_keys (d, func)
+
+

Filter a dict using func, applied to keys

+
+
filter_keys(letters, lt(67))
+
+
{65: 'A', 66: 'B'}
+
+
+
+

source

+
+
+

filter_values

+
+
 filter_values (d, func)
+
+

Filter a dict using func, applied to values

+
+
filter_values(letters, in_('FG'))
+
+
{70: 'F', 71: 'G'}
+
+
+
+

source

+
+
+

cycle

+
+
 cycle (o)
+
+

Like itertools.cycle except creates list of Nones if o is empty

+
+
test_eq(itertools.islice(cycle([1,2,3]),5), [1,2,3,1,2])
+test_eq(itertools.islice(cycle([]),3), [None]*3)
+test_eq(itertools.islice(cycle(None),3), [None]*3)
+test_eq(itertools.islice(cycle(1),3), [1,1,1])
+
+
+

source

+
+
+

zip_cycle

+
+
 zip_cycle (x, *args)
+
+

Like itertools.zip_longest but cycles through elements of all but first argument

+
+
test_eq(zip_cycle([1,2,3,4],list('abc')), [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'a')])
+
+
+

source

+
+
+

sorted_ex

+
+
 sorted_ex (iterable, key=None, reverse=False)
+
+

Like sorted, but if key is str use attrgetter; if int use itemgetter

+
+

source

+
+
+

not_

+
+
 not_ (f)
+
+

Create new function that negates result of f

+
+
def f(a): return a>0
+test_eq(f(1),True)
+test_eq(not_(f)(1),False)
+test_eq(not_(f)(a=-1),True)
+
+
+

source

+
+
+

argwhere

+
+
 argwhere (iterable, f, negate=False, **kwargs)
+
+

Like filter_ex, but return indices for matching items

+
+

source

+
+
+

filter_ex

+
+
 filter_ex (iterable, f=<function noop>, negate=False, gen=False,
+            **kwargs)
+
+

Like filter, but passing kwargs to f, defaulting f to noop, and adding negate and gen

+
+

source

+
+
+

range_of

+
+
 range_of (a, b=None, step=None)
+
+

All indices of collection a, if a is a collection, otherwise range

+
+
test_eq(range_of([1,1,1,1]), [0,1,2,3])
+test_eq(range_of(4), [0,1,2,3])
+
+
+

source

+
+
+

renumerate

+
+
 renumerate (iterable, start=0)
+
+

Same as enumerate, but returns index as 2nd element instead of 1st

+
+
test_eq(renumerate('abc'), (('a',0),('b',1),('c',2)))
+
+
+

source

+
+
+

first

+
+
 first (x, f=None, negate=False, **kwargs)
+
+

First element of x, optionally filtered by f, or None if missing

+
+
test_eq(first(['a', 'b', 'c', 'd', 'e']), 'a')
+test_eq(first([False]), False)
+test_eq(first([False], noop), None)
+
+
+

source

+
+
+

only

+
+
 only (o)
+
+

Return the only item of o, raise if o doesn’t have exactly one item

+
+

source

+
+
+

nested_attr

+
+
 nested_attr (o, attr, default=None)
+
+

Same as getattr, but if attr includes a ., then looks inside nested objects

+
+
a = SimpleNamespace(b=(SimpleNamespace(c=1)))
+test_eq(nested_attr(a, 'b.c'), getattr(getattr(a, 'b'), 'c'))
+test_eq(nested_attr(a, 'b.d'), None)
+
+
+

source

+
+
+

nested_setdefault

+
+
 nested_setdefault (o, attr, default)
+
+

Same as setdefault, but if attr includes a ., then looks inside nested objects

+
+

source

+
+
+

nested_callable

+
+
 nested_callable (o, attr)
+
+

Same as nested_attr but if not found will return noop

+
+
a = SimpleNamespace(b=(SimpleNamespace(c=1)))
+test_eq(nested_callable(a, 'b.c'), getattr(getattr(a, 'b'), 'c'))
+test_eq(nested_callable(a, 'b.d'), noop)
+
+
+

source

+
+
+

nested_idx

+
+
 nested_idx (coll, *idxs)
+
+

Index into nested collections, dicts, etc, with idxs

+
+
a = {'b':[1,{'c':2}]}
+test_eq(nested_idx(a, 'nope'), None)
+test_eq(nested_idx(a, 'nope', 'nup'), None)
+test_eq(nested_idx(a, 'b', 3), None)
+test_eq(nested_idx(a), a)
+test_eq(nested_idx(a, 'b'), [1,{'c':2}])
+test_eq(nested_idx(a, 'b', 1), {'c':2})
+test_eq(nested_idx(a, 'b', 1, 'c'), 2)
+
+
+
a = SimpleNamespace(b=[1,{'c':2}])
+test_eq(nested_idx(a, 'nope'), None)
+test_eq(nested_idx(a, 'nope', 'nup'), None)
+test_eq(nested_idx(a, 'b', 3), None)
+test_eq(nested_idx(a), a)
+test_eq(nested_idx(a, 'b'), [1,{'c':2}])
+test_eq(nested_idx(a, 'b', 1), {'c':2})
+test_eq(nested_idx(a, 'b', 1, 'c'), 2)
+
+
+

source

+
+
+

set_nested_idx

+
+
 set_nested_idx (coll, value, *idxs)
+
+

Set value indexed like `nested_idx

+
+
set_nested_idx(a, 3, 'b', 0)
+test_eq(nested_idx(a, 'b', 0), 3)
+
+
+

source

+
+
+

val2idx

+
+
 val2idx (x)
+
+

Dict from value to index

+
+
test_eq(val2idx([1,2,3]), {3:2,1:0,2:1})
+
+
+

source

+
+
+

uniqueify

+
+
 uniqueify (x, sort=False, bidir=False, start=None)
+
+

Unique elements in x, optional sort, optional return reverse correspondence, optional prepend with elements.

+
+
t = [1,1,0,5,0,3]
+test_eq(uniqueify(t),[1,0,5,3])
+test_eq(uniqueify(t, sort=True),[0,1,3,5])
+test_eq(uniqueify(t, start=[7,8,6]), [7,8,6,1,0,5,3])
+v,o = uniqueify(t, bidir=True)
+test_eq(v,[1,0,5,3])
+test_eq(o,{1:0, 0: 1, 5: 2, 3: 3})
+v,o = uniqueify(t, sort=True, bidir=True)
+test_eq(v,[0,1,3,5])
+test_eq(o,{0:0, 1: 1, 3: 2, 5: 3})
+
+
+

source

+
+
+

loop_first_last

+
+
 loop_first_last (values)
+
+

Iterate and generate a tuple with a flag for first and last value.

+
+
test_eq(loop_first_last(range(3)), [(True,False,0), (False,False,1), (False,True,2)])
+
+
+

source

+
+
+

loop_first

+
+
 loop_first (values)
+
+

Iterate and generate a tuple with a flag for first value.

+
+
test_eq(loop_first(range(3)), [(True,0), (False,1), (False,2)])
+
+
+

source

+
+
+

loop_last

+
+
 loop_last (values)
+
+

Iterate and generate a tuple with a flag for last value.

+
+
test_eq(loop_last(range(3)), [(False,0), (False,1), (True,2)])
+
+
+

source

+
+
+

first_match

+
+
 first_match (lst, f, default=None)
+
+

First element of lst matching predicate f, or default if none

+
+
a = [0,2,4,5,6,7,10]
+test_eq(first_match(a, lambda o:o%2), 3)
+
+
+

source

+
+
+

last_match

+
+
 last_match (lst, f, default=None)
+
+

Last element of lst matching predicate f, or default if none

+
+
test_eq(last_match(a, lambda o:o%2), 5)
+
+
+
+
+

fastuple

+

A tuple with extended functionality.

+
+

source

+
+

fastuple

+
+
 fastuple (x=None, *rest)
+
+

A tuple with elementwise ops and more friendly init behavior

+
+
+

Friendly init behavior

+

Common failure modes when trying to initialize a tuple in python:

+
tuple(3)
+> TypeError: 'int' object is not iterable
+

or

+
tuple(3, 4)
+> TypeError: tuple expected at most 1 arguments, got 2
+

However, fastuple allows you to define tuples like this and in the usual way:

+
+
test_eq(fastuple(3), (3,))
+test_eq(fastuple(3,4), (3, 4))
+test_eq(fastuple((3,4)), (3, 4))
+
+
+
+

Elementwise operations

+
+

source

+
+
fastuple.add
+
+
 fastuple.add (*args)
+
+

+ is already defined in tuple for concat, so use add instead

+
+
test_eq(fastuple.add((1,1),(2,2)), (3,3))
+test_eq_type(fastuple(1,1).add(2), fastuple(3,3))
+test_eq(fastuple('1','2').add('2'), fastuple('12','22'))
+
+
+

source

+
+
+
fastuple.mul
+
+
 fastuple.mul (*args)
+
+

* is already defined in tuple for replicating, so use mul instead

+
+
test_eq_type(fastuple(1,1).mul(2), fastuple(2,2))
+
+
+
+
+

Other Elementwise Operations

+

Additionally, the following elementwise operations are available: - le: less than or equal - eq: equal - gt: greater than - min: minimum of

+
+
test_eq(fastuple(3,1).le(1), (False, True))
+test_eq(fastuple(3,1).eq(1), (False, True))
+test_eq(fastuple(3,1).gt(1), (True, False))
+test_eq(fastuple(3,1).min(2), (2,1))
+
+

You can also do other elementwise operations like negate a fastuple, or subtract two fastuples:

+
+
test_eq(-fastuple(1,2), (-1,-2))
+test_eq(~fastuple(1,0,1), (False,True,False))
+
+test_eq(fastuple(1,1)-fastuple(2,2), (-1,-1))
+
+
+
test_eq(type(fastuple(1)), fastuple)
+test_eq_type(fastuple(1,2), fastuple(1,2))
+test_ne(fastuple(1,2), fastuple(1,3))
+test_eq(fastuple(), ())
+
+
+
+
+

Functions on Functions

+

Utilities for functional programming or for defining, modifying, or debugging functions.

+
+

source

+
+

bind

+
+
 bind (func, *pargs, **pkwargs)
+
+

Same as partial, except you can use arg0 arg1 etc param placeholders

+

bind is the same as partial, but also allows you to reorder positional arguments using variable name(s) arg{i} where i refers to the zero-indexed positional argument. bind as implemented currently only supports reordering of up to the first 5 positional arguments.

+

Consider the function myfunc below, which has 3 positional arguments. These arguments can be referenced as arg0, arg1, and arg1, respectively.

+
+
def myfn(a,b,c,d=1,e=2): return(a,b,c,d,e)
+
+

In the below example we bind the positional arguments of myfn as follows:

+
    +
  • The second input 14, referenced by arg1, is substituted for the first positional argument.
  • +
  • We supply a default value of 17 for the second positional argument.
  • +
  • The first input 19, referenced by arg0, is subsituted for the third positional argument.
  • +
+
+
test_eq(bind(myfn, arg1, 17, arg0, e=3)(19,14), (14,17,19,1,3))
+
+

In this next example:

+
    +
  • We set the default value to 17 for the first positional argument.
  • +
  • The first input 19 refrenced by arg0, becomes the second positional argument.
  • +
  • The second input 14 becomes the third positional argument.
  • +
  • We override the default the value for named argument e to 3.
  • +
+
+
test_eq(bind(myfn, 17, arg0, e=3)(19,14), (17,19,14,1,3))
+
+

This is an example of using bind like partial and do not reorder any arguments:

+
+
test_eq(bind(myfn)(17,19,14), (17,19,14,1,2))
+
+

bind can also be used to change default values. In the below example, we use the first input 3 to override the default value of the named argument e, and supply default values for the first three positional arguments:

+
+
test_eq(bind(myfn, 17,19,14,e=arg0)(3), (17,19,14,1,3))
+
+
+

source

+
+
+

mapt

+
+
 mapt (func, *iterables)
+
+

Tuplified map

+
+
t = [0,1,2,3]
+test_eq(mapt(operator.neg, t), (0,-1,-2,-3))
+
+
+

source

+
+
+

map_ex

+
+
 map_ex (iterable, f, *args, gen=False, **kwargs)
+
+

Like map, but use bind, and supports str and indexing

+
+
test_eq(map_ex(t,operator.neg), [0,-1,-2,-3])
+
+

If f is a string then it is treated as a format string to create the mapping:

+
+
test_eq(map_ex(t, '#{}#'), ['#0#','#1#','#2#','#3#'])
+
+

If f is a dictionary (or anything supporting __getitem__) then it is indexed to create the mapping:

+
+
test_eq(map_ex(t, list('abcd')), list('abcd'))
+
+

You can also pass the same arg params that bind accepts:

+
+
def f(a=None,b=None): return b
+test_eq(map_ex(t, f, b=arg0), range(4))
+
+
+

source

+
+
+

compose

+
+
 compose (*funcs, order=None)
+
+

Create a function that composes all functions in funcs, passing along remaining *args and **kwargs to all

+
+
f1 = lambda o,p=0: (o*2)+p
+f2 = lambda o,p=1: (o+1)/p
+test_eq(f2(f1(3)), compose(f1,f2)(3))
+test_eq(f2(f1(3,p=3),p=3), compose(f1,f2)(3,p=3))
+test_eq(f2(f1(3,  3),  3), compose(f1,f2)(3,  3))
+
+f1.order = 1
+test_eq(f1(f2(3)), compose(f1,f2, order="order")(3))
+
+
+

source

+
+
+

maps

+
+
 maps (*args, retain=<function noop>)
+
+

Like map, except funcs are composed first

+
+
test_eq(maps([1]), [1])
+test_eq(maps(operator.neg, [1,2]), [-1,-2])
+test_eq(maps(operator.neg, operator.neg, [1,2]), [1,2])
+
+
+

source

+
+
+

partialler

+
+
 partialler (f, *args, order=None, **kwargs)
+
+

Like functools.partial but also copies over docstring

+
+
def _f(x,a=1):
+    "test func"
+    return x-a
+_f.order=1
+
+f = partialler(_f, 2)
+test_eq(f.order, 1)
+test_eq(f(3), -1)
+f = partialler(_f, a=2, order=3)
+test_eq(f.__doc__, "test func")
+test_eq(f.order, 3)
+test_eq(f(3), _f(3,2))
+
+
+
class partial0:
+    "Like `partialler`, but args passed to callable are inserted at started, instead of at end"
+    def __init__(self, f, *args, order=None, **kwargs):
+        self.f,self.args,self.kwargs = f,args,kwargs
+        self.order = ifnone(order, getattr(f,'order',None))
+        self.__doc__ = f.__doc__
+
+    def __call__(self, *args, **kwargs): return self.f(*args, *self.args, **kwargs, **self.kwargs)
+
+
+
f = partial0(_f, 2)
+test_eq(f.order, 1)
+test_eq(f(3), 1) # NB: different to `partialler` example
+
+
+

source

+
+
+

instantiate

+
+
 instantiate (t)
+
+

Instantiate t if it’s a type, otherwise do nothing

+
+
test_eq_type(instantiate(int), 0)
+test_eq_type(instantiate(1), 1)
+
+
+

source

+
+
+

using_attr

+
+
 using_attr (f, attr)
+
+

Construct a function which applies f to the argument’s attribute attr

+
+
t = Path('/a/b.txt')
+f = using_attr(str.upper, 'name')
+test_eq(f(t), 'B.TXT')
+
+
+
+

Self (with an uppercase S)

+

A Concise Way To Create Lambdas

+

This is a concise way to create lambdas that are calling methods on an object (note the capitalization!)

+

Self.sum(), for instance, is a shortcut for lambda o: o.sum().

+
+
f = Self.sum()
+x = np.array([3.,1])
+test_eq(f(x), 4.)
+
+# This is equivalent to above
+f = lambda o: o.sum()
+x = np.array([3.,1])
+test_eq(f(x), 4.)
+
+f = Self.argmin()
+arr = np.array([1,2,3,4,5])
+test_eq(f(arr), arr.argmin())
+
+f = Self.sum().is_integer()
+x = np.array([3.,1])
+test_eq(f(x), True)
+
+f = Self.sum().real.is_integer()
+x = np.array([3.,1])
+test_eq(f(x), True)
+
+f = Self.imag()
+test_eq(f(3), 0)
+
+f = Self[1]
+test_eq(f(x), 1)
+
+

Self is also callable, which creates a function which calls any function passed to it, using the arguments passed to Self:

+
+
def f(a, b=3): return a+b+2
+def g(a, b=3): return a*b
+fg = Self(1,b=2)
+list(map(fg, [f,g]))
+
+
[5, 2]
+
+
+
+
+
+

Patching

+
+

source

+
+

copy_func

+
+
 copy_func (f)
+
+

Copy a non-builtin function (NB copy.copy does not work for this)

+

Sometimes it may be desirable to make a copy of a function that doesn’t point to the original object. When you use Python’s built in copy.copy or copy.deepcopy to copy a function, you get a reference to the original object:

+
+
import copy as cp
+
+
+
def foo(): pass
+a = cp.copy(foo)
+b = cp.deepcopy(foo)
+
+a.someattr = 'hello' # since a and b point at the same object, updating a will update b
+test_eq(b.someattr, 'hello')
+
+assert a is foo and b is foo
+
+

However, with copy_func, you can retrieve a copy of a function without a reference to the original object:

+
+
c = copy_func(foo) # c is an indpendent object
+assert c is not foo
+
+
+
def g(x, *, y=3): return x+y
+test_eq(copy_func(g)(4), 7)
+
+
+

source

+
+
+

patch_to

+
+
 patch_to (cls, as_prop=False, cls_method=False)
+
+

Decorator: add f to cls

+

The @patch_to decorator allows you to monkey patch a function into a class as a method:

+
+
class _T3(int): pass  
+
+@patch_to(_T3)
+def func1(self, a): return self+a
+
+t = _T3(1) # we initialized `t` to a type int = 1
+test_eq(t.func1(2), 3) # we add 2 to `t`, so 2 + 1 = 3
+
+

You can access instance properties in the usual way via self:

+
+
class _T4():
+    def __init__(self, g): self.g = g
+        
+@patch_to(_T4)
+def greet(self, x): return self.g + x
+        
+t = _T4('hello ') # this sets self.g = 'hello '
+test_eq(t.greet('world'), 'hello world') #t.greet('world') will append 'world' to 'hello '
+
+

You can instead specify that the method should be a class method by setting cls_method=True:

+
+
class _T5(int): attr = 3 # attr is a class attribute we will access in a later method
+    
+@patch_to(_T5, cls_method=True)
+def func(cls, x): return cls.attr + x # you can access class attributes in the normal way
+
+test_eq(_T5.func(4), 7)
+
+

Additionally you can specify that the function you want to patch should be a class attribute with as_prop=True:

+
+
@patch_to(_T5, as_prop=True)
+def add_ten(self): return self + 10
+
+t = _T5(4)
+test_eq(t.add_ten, 14)
+
+

Instead of passing one class to the @patch_to decorator, you can pass multiple classes in a tuple to simulteanously patch more than one class with the same method:

+
+
class _T6(int): pass
+class _T7(int): pass
+
+@patch_to((_T6,_T7))
+def func_mult(self, a): return self*a
+
+t = _T6(2)
+test_eq(t.func_mult(4), 8)
+t = _T7(2)
+test_eq(t.func_mult(4), 8)
+
+
+

source

+
+
+

patch

+
+
 patch (f=None, as_prop=False, cls_method=False)
+
+

Decorator: add f to the first parameter’s class (based on f’s type annotations)

+

@patch is an alternative to @patch_to that allows you similarly monkey patch class(es) by using type annotations:

+
+
class _T8(int): pass  
+
+@patch
+def func(self:_T8, a): return self+a
+
+t = _T8(1)  # we initilized `t` to a type int = 1
+test_eq(t.func(3), 4) # we add 3 to `t`, so 3 + 1 = 4
+test_eq(t.func.__qualname__, '_T8.func')
+
+

Similarly to patch_to, you can supply a union of classes instead of a single class in your type annotations to patch multiple classes:

+
+
class _T9(int): pass 
+
+@patch
+def func2(x:_T8|_T9, a): return x*a # will patch both _T8 and _T9
+
+t = _T8(2)
+test_eq(t.func2(4), 8)
+test_eq(t.func2.__qualname__, '_T8.func2')
+
+t = _T9(2)
+test_eq(t.func2(4), 8)
+test_eq(t.func2.__qualname__, '_T9.func2')
+
+

Just like patch_to decorator you can use as_prop and cls_method parameters with patch decorator:

+
+
@patch(as_prop=True)
+def add_ten(self:_T5): return self + 10
+
+t = _T5(4)
+test_eq(t.add_ten, 14)
+
+
+
class _T5(int): attr = 3 # attr is a class attribute we will access in a later method
+    
+@patch(cls_method=True)
+def func(cls:_T5, x): return cls.attr + x # you can access class attributes in the normal way
+
+test_eq(_T5.func(4), 7)
+
+
+

source

+
+
+

patch_property

+
+
 patch_property (f)
+
+

Deprecated; use patch(as_prop=True) instead

+

Patching classmethod shouldn’t affect how python’s inheritance works

+
+
class FastParent: pass
+
+@patch(cls_method=True)
+def type_cls(cls: FastParent): return cls
+
+class FastChild(FastParent): pass
+
+parent = FastParent()
+test_eq(parent.type_cls(), FastParent)
+
+child = FastChild()
+test_eq(child.type_cls(), FastChild)
+
+
+
+
+

Other Helpers

+
+

source

+
+

compile_re

+
+
 compile_re (pat)
+
+

Compile pat if it’s not None

+
+
assert compile_re(None) is None
+assert compile_re('a').match('ab')
+
+
+

source

+
+

ImportEnum

+
+
 ImportEnum (value, names=None, module=None, qualname=None, type=None,
+             start=1)
+
+

An Enum that can have its values imported

+
+
_T = ImportEnum('_T', {'foobar':1, 'goobar':2})
+_T.imports()
+test_eq(foobar, _T.foobar)
+test_eq(goobar, _T.goobar)
+
+
+

source

+
+
+

StrEnum

+
+
 StrEnum (value, names=None, module=None, qualname=None, type=None,
+          start=1)
+
+

An ImportEnum that behaves like a str

+
+

source

+
+
+
+

str_enum

+
+
 str_enum (name, *vals)
+
+

Simplified creation of StrEnum types

+
+

source

+
+

ValEnum

+
+
 ValEnum (value, names=None, module=None, qualname=None, type=None,
+          start=1)
+
+

An ImportEnum that stringifies using values

+
+
_T = str_enum('_T', 'a', 'b')
+test_eq(f'{_T.a}', 'a')
+test_eq(_T.a, 'a')
+test_eq(list(_T.__members__), ['a','b'])
+print(_T.a, _T.a.upper())
+
+
a A
+
+
+
+

source

+
+
+

Stateful

+
+
 Stateful (*args, **kwargs)
+
+

A base class/mixin for objects that should not serialize all their state

+
+
class _T(Stateful):
+    def __init__(self):
+        super().__init__()
+        self.a=1
+        self._state['test']=2
+
+t = _T()
+t2 = pickle.loads(pickle.dumps(t))
+test_eq(t.a,1)
+test_eq(t._state['test'],2)
+test_eq(t2.a,1)
+test_eq(t2._state,{})
+
+

Override _init_state to do any necessary setup steps that are required during __init__ or during deserialization (e.g. pickle.load). Here’s an example of how Stateful simplifies the official Python example for Handling Stateful Objects.

+
+
class TextReader(Stateful):
+    """Print and number lines in a text file."""
+    _stateattrs=('file',)
+    def __init__(self, filename):
+        self.filename,self.lineno = filename,0
+        super().__init__()
+
+    def readline(self):
+        self.lineno += 1
+        line = self.file.readline()
+        if line: return f"{self.lineno}: {line.strip()}"
+
+    def _init_state(self):
+        self.file = open(self.filename)
+        for _ in range(self.lineno): self.file.readline()
+
+
+
reader = TextReader("00_test.ipynb")
+print(reader.readline())
+print(reader.readline())
+
+new_reader = pickle.loads(pickle.dumps(reader))
+print(reader.readline())
+
+
1: {
+2: "cells": [
+3: {
+
+
+
+

source

+
+
+
+

NotStr

+
+
 NotStr (s)
+
+

Behaves like a str, but isn’t an instance of one

+
+
s = NotStr("hello")
+assert not isinstance(s, str)
+test_eq(s, 'hello')
+test_eq(s*2, 'hellohello')
+test_eq(len(s), 5)
+
+
+

source

+
+

PrettyString

+

Little hack to get strings to show properly in Jupyter.

+

Allow strings with special characters to render properly in Jupyter. Without calling print() strings with special characters are displayed like so:

+
+
with_special_chars='a string\nwith\nnew\nlines and\ttabs'
+with_special_chars
+
+
'a string\nwith\nnew\nlines and\ttabs'
+
+
+

We can correct this with PrettyString:

+
+
PrettyString(with_special_chars)
+
+
a string
+with
+new
+lines and   tabs
+
+
+
+

source

+
+
+
+

even_mults

+
+
 even_mults (start, stop, n)
+
+

Build log-stepped array from start to stop in n steps.

+
+
test_eq(even_mults(2,8,3), [2,4,8])
+test_eq(even_mults(2,32,5), [2,4,8,16,32])
+test_eq(even_mults(2,8,1), 8)
+
+
+

source

+
+
+

num_cpus

+
+
 num_cpus ()
+
+

Get number of cpus

+
+
num_cpus()
+
+
8
+
+
+
+

source

+
+
+

add_props

+
+
 add_props (f, g=None, n=2)
+
+

Create properties passing each of range(n) to f

+
+
class _T(): a,b = add_props(lambda i,x:i*2)
+
+t = _T()
+test_eq(t.a,0)
+test_eq(t.b,2)
+
+
+
class _T(): 
+    def __init__(self, v): self.v=v
+    def _set(i, self, v): self.v[i] = v
+    a,b = add_props(lambda i,x: x.v[i], _set)
+
+t = _T([0,2])
+test_eq(t.a,0)
+test_eq(t.b,2)
+t.a = t.a+1
+t.b = 3
+test_eq(t.a,1)
+test_eq(t.b,3)
+
+
+

source

+
+
+

typed

+
+
 typed (f)
+
+

Decorator to check param and return types at runtime

+

typed validates argument types at runtime. This is in contrast to MyPy which only offers static type checking.

+

For example, a TypeError will be raised if we try to pass an integer into the first argument of the below function:

+
+
@typed
+def discount(price:int, pct:float): 
+    return (1-pct) * price
+
+with ExceptionExpected(TypeError): discount(100.0, .1)
+
+

We can also optionally allow multiple types by enumarating the types in a tuple as illustrated below:

+
+
def discount(price:int|float, pct:float): 
+    return (1-pct) * price
+
+assert 90.0 == discount(100.0, .1)
+
+
+
@typed
+def foo(a:int, b:str='a'): return a
+test_eq(foo(1, '2'), 1)
+
+with ExceptionExpected(TypeError): foo(1,2)
+
+@typed
+def foo()->str: return 1
+with ExceptionExpected(TypeError): foo()
+
+@typed
+def foo()->str: return '1'
+assert foo()
+
+

typed works with classes, too:

+
+
class Foo:
+    @typed
+    def __init__(self, a:int, b: int, c:str): pass
+    @typed
+    def test(cls, d:str): return d
+
+with ExceptionExpected(TypeError): Foo(1, 2, 3) 
+with ExceptionExpected(TypeError): Foo(1,2, 'a string').test(10)
+
+
+

source

+
+
+

exec_new

+
+
 exec_new (code)
+
+

Execute code in a new environment and return it

+
+
g = exec_new('a=1')
+test_eq(g['a'], 1)
+
+
+

source

+
+
+

exec_import

+
+
 exec_import (mod, sym)
+
+

Import sym from mod in a new environment

+
+

source

+
+
+

str2bool

+
+
 str2bool (s)
+
+

Case-insensitive convert string s too a bool (y,yes,t,true,on,1->True)

+

True values are ‘y’, ‘yes’, ‘t’, ‘true’, ‘on’, and ‘1’; false values are ‘n’, ‘no’, ‘f’, ‘false’, ‘off’, and ‘0’. Raises ValueError if ‘val’ is anything else.

+
+
for o in "y YES t True on 1".split(): assert str2bool(o)
+for o in "n no FALSE off 0".split(): assert not str2bool(o)
+for o in 0,None,'',False: assert not str2bool(o)
+for o in 1,True: assert str2bool(o)
+
+
+
+
+

Notebook functions

+
+
+

ipython_shell

+
+
 ipython_shell ()
+
+

Same as get_ipython but returns False if not in IPython

+
+
+
+

in_ipython

+
+
 in_ipython ()
+
+

Check if code is running in some kind of IPython environment

+
+
+
+

in_colab

+
+
 in_colab ()
+
+

Check if the code is running in Google Colaboratory

+
+
+
+

in_jupyter

+
+
 in_jupyter ()
+
+

Check if the code is running in a jupyter notebook

+
+
+
+

in_notebook

+
+
 in_notebook ()
+
+

Check if the code is running in a jupyter notebook

+

These variables are available as booleans in fastcore.basics as IN_IPYTHON, IN_JUPYTER, IN_COLAB and IN_NOTEBOOK.

+
+
IN_IPYTHON, IN_JUPYTER, IN_COLAB, IN_NOTEBOOK
+
+
(True, True, False, True)
+
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/dispatch.html b/dispatch.html new file mode 100644 index 00000000..5904e10f --- /dev/null +++ b/dispatch.html @@ -0,0 +1,1266 @@ + + + + + + + + + + +Type dispatch – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Type dispatch

+
+ +
+
+ Basic single and dual parameter dispatch +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from nbdev.showdoc import *
+from fastcore.test import *
+from fastcore.nb_imports import *
+
+
+

Helpers

+
+

source

+
+

lenient_issubclass

+
+
 lenient_issubclass (cls, types)
+
+

If possible return whether cls is a subclass of types, otherwise return False.

+
+
assert not lenient_issubclass(typing.Collection, list)
+assert lenient_issubclass(list, typing.Collection)
+assert lenient_issubclass(typing.Collection, object)
+assert lenient_issubclass(typing.List, typing.Collection)
+assert not lenient_issubclass(typing.Collection, typing.List)
+assert not lenient_issubclass(object, typing.Callable)
+
+
+

source

+
+
+

sorted_topologically

+
+
 sorted_topologically (iterable, cmp=<built-in function lt>,
+                       reverse=False)
+
+

Return a new list containing all items from the iterable sorted topologically

+
+
td = [3, 1, 2, 5]
+test_eq(sorted_topologically(td), [1, 2, 3, 5])
+test_eq(sorted_topologically(td, reverse=True), [5, 3, 2, 1])
+
+
+
td = {int:1, numbers.Number:2, numbers.Integral:3}
+test_eq(sorted_topologically(td, cmp=lenient_issubclass), [int, numbers.Integral, numbers.Number])
+
+
+
td = [numbers.Integral, tuple, list, int, dict]
+td = sorted_topologically(td, cmp=lenient_issubclass)
+assert td.index(int) < td.index(numbers.Integral)
+
+
+
+
+

TypeDispatch

+

Type dispatch, or Multiple dispatch, allows you to change the way a function behaves based upon the input types it recevies. This is a prominent feature in some programming languages like Julia. For example, this is a conceptual example of how multiple dispatch works in Julia, returning different values depending on the input types of x and y:

+
collide_with(x::Asteroid, y::Asteroid) = ... 
+# deal with asteroid hitting asteroid
+
+collide_with(x::Asteroid, y::Spaceship) = ... 
+# deal with asteroid hitting spaceship
+
+collide_with(x::Spaceship, y::Asteroid) = ... 
+# deal with spaceship hitting asteroid
+
+collide_with(x::Spaceship, y::Spaceship) = ... 
+# deal with spaceship hitting spaceship
+

Type dispatch can be especially useful in data science, where you might allow different input types (i.e. numpy arrays and pandas dataframes) to function that processes data. Type dispatch allows you to have a common API for functions that do similar tasks.

+

The TypeDispatch class allows us to achieve type dispatch in Python. It contains a dictionary that maps types from type annotations to functions, which ensures that the proper function is called when passed inputs.

+
+

source

+
+

TypeDispatch

+
+
 TypeDispatch (funcs=(), bases=())
+
+

Dictionary-like object; __getitem__ matches keys of types using issubclass

+

To demonstrate how TypeDispatch works, we define a set of functions that accept a variety of input types, specified with different type annotations:

+
+
def f2(x:int, y:float): return x+y              #int and float for 2nd arg
+def f_nin(x:numbers.Integral)->int:  return x+1 #integral numeric
+def f_ni2(x:int): return x                      #integer
+def f_bll(x:bool|list): return x              #bool or list
+def f_num(x:numbers.Number): return x           #Number (root of numerics)
+
+

We can optionally initialize TypeDispatch with a list of functions we want to search. Printing an instance of TypeDispatch will display convenient mapping of types -> functions:

+
+
t = TypeDispatch([f_nin,f_ni2,f_num,f_bll,None])
+t
+
+
(bool,object) -> f_bll
+(int,object) -> f_ni2
+(Integral,object) -> f_nin
+(Number,object) -> f_num
+(list,object) -> f_bll
+(object,object) -> NoneType
+
+
+

Note that only the first two arguments are used for TypeDispatch. If your function only contains one argument, the second parameter will be shown as object. If you pass None into TypeDispatch, then this will be displayed as (object, object) -> NoneType.

+

TypeDispatch is a dictionary-like object, which means that you can retrieve a function by the associated type annotation. For example, the statement:

+
t[float]
+

Will return f_num because that is the matching function that has a type annotation that is a super-class of of float - numbers.Number:

+
+
assert issubclass(float, numbers.Number)
+test_eq(t[float], f_num)
+
+

The same is true for other types as well:

+
+
test_eq(t[np.int32], f_nin)
+test_eq(t[bool], f_bll)
+test_eq(t[list], f_bll)
+test_eq(t[np.int32], f_nin)
+
+

If you try to get a type that doesn’t match, TypeDispatch will return None:

+
+
test_eq(t[str], None)
+
+
+

source

+
+
+

TypeDispatch.add

+
+
 TypeDispatch.add (f)
+
+

Add type t and function f

+

This method allows you to add an additional function to an existing TypeDispatch instance :

+
+
def f_col(x:typing.Collection): return x
+t.add(f_col)
+test_eq(t[str], f_col)
+t
+
+
(bool,object) -> f_bll
+(int,object) -> f_ni2
+(Integral,object) -> f_nin
+(Number,object) -> f_num
+(list,object) -> f_bll
+(typing.Collection,object) -> f_col
+(object,object) -> NoneType
+
+
+

If you accidentally add the same function more than once things will still work as expected:

+
+
t.add(f_ni2) 
+test_eq(t[int], f_ni2)
+
+

However, if you add a function that has a type collision that raises an ambiguity, this will automatically resolve to the latest function added:

+
+
def f_ni3(z:int): return z # collides with f_ni2 with same type annotations
+t.add(f_ni3) 
+test_eq(t[int], f_ni3)
+
+
+

Using bases:

+

The argument bases can optionally accept a single instance of TypeDispatch or a collection (i.e. a tuple or list) of TypeDispatch objects. This can provide functionality similar to multiple inheritance.

+

These are searched for matching functions if no match in your list of functions:

+
+
def f_str(x:str): return x+'1'
+
+t = TypeDispatch([f_nin,f_ni2,f_num,f_bll,None])
+t2 = TypeDispatch(f_str, bases=t) # you can optionally supply a list of TypeDispatch objects for `bases`.
+t2
+
+
(str,object) -> f_str
+(bool,object) -> f_bll
+(int,object) -> f_ni2
+(Integral,object) -> f_nin
+(Number,object) -> f_num
+(list,object) -> f_bll
+(object,object) -> NoneType
+
+
+
+
test_eq(t2[int], f_ni2)       # searches `t` b/c not found in `t2`
+test_eq(t2[np.int32], f_nin)  # searches `t` b/c not found in `t2`
+test_eq(t2[float], f_num)     # searches `t` b/c not found in `t2`
+test_eq(t2[bool], f_bll)      # searches `t` b/c not found in `t2`
+test_eq(t2[str], f_str)       # found in `t`!
+test_eq(t2('a'), 'a1')        # found in `t`!, and uses __call__
+
+o = np.int32(1)
+test_eq(t2(o), 2)             # found in `t2` and uses __call__
+
+
+
+

Up To Two Arguments

+

TypeDispatch supports up to two arguments when searching for the appropriate function. The following functions f1 and f2 both have two parameters:

+
+
def f1(x:numbers.Integral, y): return x+1  #Integral is a numeric type
+def f2(x:int, y:float): return x+y
+t = TypeDispatch([f1,f2])
+t
+
+
(int,float) -> f2
+(Integral,object) -> f1
+
+
+

You can lookup functions from a TypeDispatch instance with two parameters like this:

+
+
test_eq(t[np.int32], f1)
+test_eq(t[int,float], f2)
+
+

Keep in mind that anything beyond the first two parameters are ignored, and any collisions will be resolved in favor of the most recent function added. In the below example, f1 is ignored in favor of f2 because the first two parameters have identical type hints:

+
+
def f1(a:str, b:int, c:list): return a
+def f2(a: str, b:int): return b
+t = TypeDispatch([f1,f2])
+test_eq(t[str, int], f2)
+t
+
+
(str,int) -> f2
+
+
+
+
+

Matching

+

Type Dispatch matches types with functions according to whether the supplied class is a subclass or the same class of the type annotation(s) of associated functions.

+

Let’s consider an example where we try to retrieve the function corresponding to types of [np.int32, float].

+

In this scenario, f2 will not be matched. This is because the first type annotation of f2, int, is not a superclass (or the same class) of np.int32:

+
+
def f1(x:numbers.Integral, y): return x+1
+def f2(x:int, y:float): return x+y
+t = TypeDispatch([f1,f2])
+
+assert not issubclass(np.int32, int)
+
+

Instead, f1 is a valid match, as its first argument is annoted with the type numbers.Integeral, which np.int32 is a subclass of:

+
+
assert issubclass(np.int32, numbers.Integral)
+test_eq(t[np.int32,float], f1)
+
+

In f1 , the 2nd parameter y is not annotated, which means TypeDispatch will match anything where the first argument matches int that is not matched with anything else:

+
+
assert issubclass(int, numbers.Integral) # int is a subclass of numbers.Integral
+test_eq(t[int], f1)
+test_eq(t[int,int], f1)
+
+

If no match is possible, None is returned:

+
+
test_eq(t[float,float], None)
+
+
+

source

+
+
+
+

TypeDispatch.__call__

+
+
 TypeDispatch.__call__ (*args, **kwargs)
+
+

Call self as a function.

+

TypeDispatch is also callable. When you call an instance of TypeDispatch, it will execute the relevant function:

+
+
def f_arr(x:np.ndarray): return x.sum()
+def f_int(x:np.int32): return x+1
+t = TypeDispatch([f_arr, f_int])
+
+arr = np.array([5,4,3,2,1])
+test_eq(t(arr), 15) # dispatches to f_arr
+
+o = np.int32(1)
+test_eq(t(o), 2) # dispatches to f_int
+assert t.first() is not None
+
+

You can also call an instance of of TypeDispatch when there are two parameters:

+
+
def f1(x:numbers.Integral, y): return x+1
+def f2(x:int, y:float): return x+y
+t = TypeDispatch([f1,f2])
+
+test_eq(t(3,2.0), 5)
+test_eq(t(3,2), 4)
+
+

When no match is found, a TypeDispatch instance becomes an identity function. This default behavior is leveraged by fasatai for data transformations to provide a sensible default when a matching function cannot be found.

+
+
test_eq(t('a'), 'a')
+
+
+

source

+
+
+

TypeDispatch.returns

+
+
 TypeDispatch.returns (x)
+
+

Get the return type of annotation of x.

+

You can optionally pass an object to TypeDispatch.returns and get the return type annotation back:

+
+
def f1(x:int) -> np.ndarray: return np.array(x)
+def f2(x:str) -> float: return List
+def f3(x:float): return List # f3 has no return type annotation
+
+t = TypeDispatch([f1, f2, f3])
+
+test_eq(t.returns(1), np.ndarray)  # dispatched to f1
+test_eq(t.returns('Hello'), float) # dispatched to f2
+test_eq(t.returns(1.0), None)      # dispatched to f3
+
+class _Test: pass
+_test = _Test()
+test_eq(t.returns(_test), None) # type `_Test` not found, so None returned
+
+
+

Using TypeDispatch With Methods

+

You can use TypeDispatch when defining methods as well:

+
+
def m_nin(self, x:str|numbers.Integral): return str(x)+'1'
+def m_bll(self, x:bool): self.foo='a'
+def m_num(self, x:numbers.Number): return x*2
+
+t = TypeDispatch([m_nin,m_num,m_bll])
+class A: f = t # set class attribute `f` equal to a TypeDispatch instance
+    
+a = A()
+test_eq(a.f(1), '11')  #dispatch to m_nin
+test_eq(a.f(1.), 2.)   #dispatch to m_num
+test_is(a.f.inst, a)
+
+a.f(False) # this triggers t.m_bll to run, which sets self.foo to 'a'
+test_eq(a.foo, 'a')
+
+

As discussed in TypeDispatch.__call__, when there is not a match, TypeDispatch.__call__ becomes an identity function. In the below example, a tuple does not match any type annotations so a tuple is returned:

+
+
test_eq(a.f(()), ())
+
+

We extend the previous example by using bases to add an additional method that supports tuples:

+
+
def m_tup(self, x:tuple): return x+(1,)
+t2 = TypeDispatch(m_tup, bases=t)
+
+class A2: f = t2
+a2 = A2()
+test_eq(a2.f(1), '11')
+test_eq(a2.f(1.), 2.)
+test_is(a2.f.inst, a2)
+a2.f(False)
+test_eq(a2.foo, 'a')
+test_eq(a2.f(()), (1,))
+
+
+
+

Using TypeDispatch With Class Methods

+

You can use TypeDispatch when defining class methods too:

+
+
def m_nin(cls, x:str|numbers.Integral): return str(x)+'1'
+def m_bll(cls, x:bool): cls.foo='a'
+def m_num(cls, x:numbers.Number): return x*2
+
+t = TypeDispatch([m_nin,m_num,m_bll])
+class A: f = t # set class attribute `f` equal to a TypeDispatch
+
+test_eq(A.f(1), '11')  #dispatch to m_nin
+test_eq(A.f(1.), 2.)   #dispatch to m_num
+test_is(A.f.owner, A)
+
+A.f(False) # this triggers t.m_bll to run, which sets A.foo to 'a'
+test_eq(A.foo, 'a')
+
+
+
+
+
+

typedispatch Decorator

+
+

source

+
+

DispatchReg

+
+
 DispatchReg ()
+
+

A global registry for TypeDispatch objects keyed by function name

+
+
@typedispatch
+def f_td_test(x, y): return f'{x}{y}'
+@typedispatch
+def f_td_test(x:numbers.Integral|int, y): return x+1
+@typedispatch
+def f_td_test(x:int, y:float): return x+y
+@typedispatch
+def f_td_test(x:int, y:int): return x*y
+
+test_eq(f_td_test(3,2.0), 5)
+assert issubclass(int, numbers.Integral)
+test_eq(f_td_test(3,2), 6)
+
+test_eq(f_td_test('a','b'), 'ab')
+
+
+

Using typedispatch With other decorators

+

You can use typedispatch with classmethod and staticmethod decorator

+
+
class A:
+    @typedispatch
+    def f_td_test(self, x:numbers.Integral, y): return x+1
+    @typedispatch
+    @classmethod
+    def f_td_test(cls, x:int, y:float): return x+y
+    @typedispatch
+    @staticmethod
+    def f_td_test(x:int, y:int): return x*y
+    
+test_eq(A.f_td_test(3,2), 6)
+test_eq(A.f_td_test(3,2.0), 5)
+test_eq(A().f_td_test(3,'2.0'), 4)
+
+
+
+
+
+

Casting

+

Now that we can dispatch on types, let’s make it easier to cast objects to a different type.

+
+

source

+
+

retain_meta

+
+
 retain_meta (x, res, as_copy=False)
+
+

Call res.set_meta(x), if it exists

+
+

source

+
+
+

default_set_meta

+
+
 default_set_meta (x, as_copy=False)
+
+

Copy over _meta from x to res, if it’s missing

+
+
+
+

(object,object) -> cast

+

Dictionary-like object; __getitem__ matches keys of types using issubclass

+

This works both for plain python classes:…

+
+
mk_class('_T1', 'a')   # mk_class is a fastai utility that constructs a class.
+class _T2(_T1): pass
+
+t = _T1(a=1)
+t2 = cast(t, _T2)        
+assert t2 is t            # t2 refers to the same object as t
+assert isinstance(t, _T2) # t also changed in-place
+assert isinstance(t2, _T2)
+
+test_eq_type(_T2(a=1), t2)
+
+

…as well as for arrays and tensors.

+
+
class _T1(ndarray): pass
+
+t = array([1])
+t2 = cast(t, _T1)
+test_eq(array([1]), t2)
+test_eq(_T1, type(t2))
+
+

To customize casting for other types, define a separate cast function with typedispatch for your type.

+
+

source

+
+
+

retain_type

+
+
 retain_type (new, old=None, typ=None, as_copy=False)
+
+

Cast new to type of old or typ if it’s a superclass

+
+
class _T(tuple): pass
+a = _T((1,2))
+b = tuple((1,2))
+c = retain_type(b, typ=_T)
+test_eq_type(c, a)
+
+

If old has a _meta attribute, its content is passed when casting new to the type of old. In the below example, only the attribute a, but not other_attr is kept, because other_attr is not in _meta:

+
+
class _A():
+    set_meta = default_set_meta
+    def __init__(self, t): self.t=t
+
+class _B1(_A):
+    def __init__(self, t, a=1):
+        super().__init__(t)
+        self._meta = {'a':a}
+        self.other_attr = 'Hello' # will not be kept after casting.
+        
+x = _B1(1, a=2)
+b = _A(1)
+c = retain_type(b, old=x)
+test_eq(c._meta, {'a': 2})
+assert not getattr(c, 'other_attr', None)
+
+
+

source

+
+
+

retain_types

+
+
 retain_types (new, old=None, typs=None)
+
+

Cast each item of new to type of matching item in old if it’s a superclass

+
+
class T(tuple): pass
+
+t1,t2 = retain_types((1,(1,(1,1))), (2,T((2,T((3,4))))))
+test_eq_type(t1, 1)
+test_eq_type(t2, T((1,T((1,1)))))
+
+t1,t2 = retain_types((1,(1,(1,1))), typs = {tuple: [int, {T: [int, {T: [int,int]}]}]})
+test_eq_type(t1, 1)
+test_eq_type(t2, T((1,T((1,1)))))
+
+
+

source

+
+
+

explode_types

+
+
 explode_types (o)
+
+

Return the type of o, potentially in nested dictionaries for thing that are listy

+
+
test_eq(explode_types((2,T((2,T((3,4)))))), {tuple: [int, {T: [int, {T: [int,int]}]}]})
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/docments.html b/docments.html new file mode 100644 index 00000000..780acf49 --- /dev/null +++ b/docments.html @@ -0,0 +1,1036 @@ + + + + + + + + + + +Docments – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Docments

+
+ +
+
+ Document parameters using comments. +
+
+ + +
+ + + + +
+ + + +
+ + + +

docments provides programmatic access to comments in function parameters and return types. It can be used to create more developer-friendly documentation, CLI, etc tools.

+
+

Why?

+

Without docments, if you want to document your parameters, you have to repeat param names in docstrings, since they’re already in the function signature. The parameters have to be kept synchronized in the two places as you change your code. Readers of your code have to look back and forth between two places to understand what’s happening. So it’s more work for you, and for your users.

+

Furthermore, to have parameter documentation formatted nicely without docments, you have to use special magic docstring formatting, often with odd quirks, which is a pain to create and maintain, and awkward to read in code. For instance, using numpy-style documentation:

+
+
def add_np(a:int, b:int=0)->int:
+    """The sum of two numbers.
+    
+    Used to demonstrate numpy-style docstrings.
+
+Parameters
+----------
+a : int
+    the 1st number to add
+b : int
+    the 2nd number to add (default: 0)
+
+Returns
+-------
+int
+    the result of adding `a` to `b`"""
+    return a+b
+
+

By comparison, here’s the same thing using docments:

+
+
def add(
+    a:int, # the 1st number to add
+    b=0,   # the 2nd number to add
+)->int:    # the result of adding `a` to `b`
+    "The sum of two numbers."
+    return a+b
+
+
+
+

Numpy docstring helper functions

+

docments also supports numpy-style docstrings, or a mix or numpy-style and docments parameter documentation. The functions in this section help get and parse this information.

+
+

source

+
+

docstring

+
+
 docstring (sym)
+
+

Get docstring for sym for functions ad classes

+
+
test_eq(docstring(add), "The sum of two numbers.")
+
+
+

source

+
+
+

parse_docstring

+
+
 parse_docstring (sym)
+
+

Parse a numpy-style docstring in sym

+
+
# parse_docstring(add_np)
+
+
+

source

+
+
+

isdataclass

+
+
 isdataclass (s)
+
+

Check if s is a dataclass but not a dataclass’ instance

+
+

source

+
+
+

get_dataclass_source

+
+
 get_dataclass_source (s)
+
+

Get source code for dataclass s

+
+

source

+
+
+

get_source

+
+
 get_source (s)
+
+

Get source code for string, function object or dataclass s

+
+

source

+
+
+

get_name

+
+
 get_name (obj)
+
+

Get the name of obj

+
+
test_eq(get_name(in_ipython), 'in_ipython')
+test_eq(get_name(L.map), 'map')
+
+
+

source

+
+
+

qual_name

+
+
 qual_name (obj)
+
+

Get the qualified name of obj

+
+
assert qual_name(docscrape) == 'fastcore.docscrape'
+
+
+
+
+

Docments

+
+

source

+
+

docments

+
+
 docments (elt, full=False, returns=True, eval_str=False)
+
+

Generates a docment

+

The returned dict has parameter names as keys, docments as values. The return value comment appears in the return, unless returns=False. Using the add definition above, we get:

+
+
def add(
+    a:int, # the 1st number to add
+    b=0,   # the 2nd number to add
+)->int:    # the result of adding `a` to `b`
+    "The sum of two numbers."
+    return a+b
+
+docments(add)
+
+
{ 'a': 'the 1st number to add',
+  'b': 'the 2nd number to add',
+  'return': 'the result of adding `a` to `b`'}
+
+
+

If you pass full=True, the values are dict of defaults, types, and docments as values. Note that the type annotation is inferred from the default value, if the annotation is empty and a default is supplied.

+
+
docments(add, full=True)
+
+
{ 'a': { 'anno': 'int',
+         'default': <class 'inspect._empty'>,
+         'docment': 'the 1st number to add'},
+  'b': { 'anno': <class 'int'>,
+         'default': 0,
+         'docment': 'the 2nd number to add'},
+  'return': { 'anno': 'int',
+              'default': <class 'inspect._empty'>,
+              'docment': 'the result of adding `a` to `b`'}}
+
+
+

To evaluate stringified annotations (from python 3.10), use eval_str:

+
+
docments(add, full=True, eval_str=True)['a']
+
+
{ 'anno': <class 'int'>,
+  'default': <class 'inspect._empty'>,
+  'docment': 'the 1st number to add'}
+
+
+

If you need more space to document a parameter, place one or more lines of comments above the parameter, or above the return type. You can mix-and-match these docment styles:

+
+
def add(
+    # The first operand
+    a:int,
+    # This is the second of the operands to the *addition* operator.
+    # Note that passing a negative value here is the equivalent of the *subtraction* operator.
+    b:int,
+)->int: # The result is calculated using Python's builtin `+` operator.
+    "Add `a` to `b`"
+    return a+b
+
+
+
docments(add)
+
+
{ 'a': 'The first operand',
+  'b': 'This is the second of the operands to the *addition* operator.\n'
+       'Note that passing a negative value here is the equivalent of the '
+       '*subtraction* operator.',
+  'return': "The result is calculated using Python's builtin `+` operator."}
+
+
+

Docments works with async functions, too:

+
+
async def add_async(
+    # The first operand
+    a:int,
+    # This is the second of the operands to the *addition* operator.
+    # Note that passing a negative value here is the equivalent of the *subtraction* operator.
+    b:int,
+)->int: # The result is calculated using Python's builtin `+` operator.
+    "Add `a` to `b`"
+    return a+b
+
+
+
test_eq(docments(add_async), docments(add))
+
+

You can also use docments with classes and methods:

+
+
class Adder:
+    "An addition calculator"
+    def __init__(self,
+        a:int, # First operand
+        b:int, # 2nd operand
+    ): self.a,self.b = a,b
+    
+    def calculate(self
+                 )->int: # Integral result of addition operator
+        "Add `a` to `b`"
+        return a+b
+
+
+
docments(Adder)
+
+
{'a': 'First operand', 'b': '2nd operand', 'return': None}
+
+
+
+
docments(Adder.calculate)
+
+
{'return': 'Integral result of addition operator', 'self': None}
+
+
+

docments can also be extracted from numpy-style docstrings:

+
+
print(add_np.__doc__)
+
+
The sum of two numbers.
+    
+    Used to demonstrate numpy-style docstrings.
+
+Parameters
+----------
+a : int
+    the 1st number to add
+b : int
+    the 2nd number to add (default: 0)
+
+Returns
+-------
+int
+    the result of adding `a` to `b`
+
+
+
+
docments(add_np)
+
+
{ 'a': 'the 1st number to add',
+  'b': 'the 2nd number to add (default: 0)',
+  'return': 'the result of adding `a` to `b`'}
+
+
+

You can even mix and match docments and numpy parameters:

+
+
def add_mixed(a:int, # the first number to add
+              b
+             )->int: # the result
+    """The sum of two numbers.
+
+Parameters
+----------
+b : int
+    the 2nd number to add (default: 0)"""
+    return a+b
+
+
+
docments(add_mixed, full=True)
+
+
{ 'a': { 'anno': 'int',
+         'default': <class 'inspect._empty'>,
+         'docment': 'the first number to add'},
+  'b': { 'anno': 'int',
+         'default': <class 'inspect._empty'>,
+         'docment': 'the 2nd number to add (default: 0)'},
+  'return': { 'anno': 'int',
+              'default': <class 'inspect._empty'>,
+              'docment': 'the result'}}
+
+
+

You can use docments with dataclasses, however if the class was defined in online notebook, docments will not contain parameters’ comments. This is because the source code is not available in the notebook. After converting the notebook to a module, the docments will be available. Thus, documentation will have correct parameters’ comments.

+

Docments even works with delegates:

+
+
from fastcore.meta import delegates
+
+
+
def _a(a:int=2): return a # First
+
+@delegates(_a)
+def _b(b:str, **kwargs): return b, (_a(**kwargs)) # Second
+
+docments(_b)
+
+
{'a': 'First', 'b': 'Second', 'return': None}
+
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/foundation.html b/foundation.html new file mode 100644 index 00000000..8ea75b12 --- /dev/null +++ b/foundation.html @@ -0,0 +1,1522 @@ + + + + + + + + + + +Foundation – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Foundation

+
+ +
+
+ The L class and helpers for it +
+
+ + +
+ + + + +
+ + + +
+ + + +
+

Foundational Functions

+
+

source

+
+

working_directory

+
+
 working_directory (path)
+
+

Change working directory to path and return to previous on exit.

+
+

source

+
+
+

add_docs

+
+
 add_docs (cls, cls_doc=None, **docs)
+
+

Copy values from docs to cls docstrings, and confirm all public methods are documented

+

add_docs allows you to add docstrings to a class and its associated methods. This function allows you to group docstrings together seperate from your code, which enables you to define one-line functions as well as organize your code more succintly. We believe this confers a number of benefits which we discuss in our style guide.

+

Suppose you have the following undocumented class:

+
+
class T:
+    def foo(self): pass
+    def bar(self): pass
+
+

You can add documentation to this class like so:

+
+
add_docs(T, cls_doc="A docstring for the class.",
+            foo="The foo method.",
+            bar="The bar method.")
+
+

Now, docstrings will appear as expected:

+
+
test_eq(T.__doc__, "A docstring for the class.")
+test_eq(T.foo.__doc__, "The foo method.")
+test_eq(T.bar.__doc__, "The bar method.")
+
+

add_docs also validates that all of your public methods contain a docstring. If one of your methods is not documented, it will raise an error:

+
+
class T:
+    def foo(self): pass
+    def bar(self): pass
+
+f=lambda: add_docs(T, "A docstring for the class.", foo="The foo method.")
+test_fail(f, contains="Missing docs")
+
+
+

source

+
+
+

docs

+
+
 docs (cls)
+
+

Decorator version of add_docs, using _docs dict

+

Instead of using add_docs, you can use the decorator docs as shown below. Note that the docstring for the class can be set with the argument cls_doc:

+
+
@docs
+class _T:
+    def f(self): pass
+    def g(cls): pass
+    
+    _docs = dict(cls_doc="The class docstring", 
+                 f="The docstring for method f.",
+                 g="A different docstring for method g.")
+
+    
+test_eq(_T.__doc__, "The class docstring")
+test_eq(_T.f.__doc__, "The docstring for method f.")
+test_eq(_T.g.__doc__, "A different docstring for method g.")
+
+

For either the docs decorator or the add_docs function, you can still define your docstrings in the normal way. Below we set the docstring for the class as usual, but define the method docstrings through the _docs attribute:

+
+
@docs
+class _T:
+    "The class docstring"
+    def f(self): pass
+    _docs = dict(f="The docstring for method f.")
+
+    
+test_eq(_T.__doc__, "The class docstring")
+test_eq(_T.f.__doc__, "The docstring for method f.")
+
+
+
+
+

is_iter

+
+
 is_iter (o)
+
+

Test whether o can be used in a for loop

+
+
assert is_iter([1])
+assert not is_iter(array(1))
+assert is_iter(array([1,2]))
+assert (o for o in range(3))
+
+
+

source

+
+
+

coll_repr

+
+
 coll_repr (c, max_n=10)
+
+

String repr of up to max_n items of (possibly lazy) collection c

+

coll_repr is used to provide a more informative __repr__ about list-like objects. coll_repr and is used by L to build a __repr__ that displays the length of a list in addition to a preview of a list.

+

Below is an example of the __repr__ string created for a list of 1000 elements:

+
+
test_eq(coll_repr(range(1000)),    '(#1000) [0,1,2,3,4,5,6,7,8,9...]')
+test_eq(coll_repr(range(1000), 5), '(#1000) [0,1,2,3,4...]')
+test_eq(coll_repr(range(10),   5),   '(#10) [0,1,2,3,4...]')
+test_eq(coll_repr(range(5),    5),    '(#5) [0,1,2,3,4]')
+
+

We can set the option max_n to optionally preview a specified number of items instead of the default:

+
+
test_eq(coll_repr(range(1000), max_n=5), '(#1000) [0,1,2,3,4...]')
+
+
+

source

+
+
+

is_bool

+
+
 is_bool (x)
+
+

Check whether x is a bool or None

+
+

source

+
+
+

mask2idxs

+
+
 mask2idxs (mask)
+
+

Convert bool mask or index list to index L

+
+
test_eq(mask2idxs([False,True,False,True]), [1,3])
+test_eq(mask2idxs(array([False,True,False,True])), [1,3])
+test_eq(mask2idxs(array([1,2,3])), [1,2,3])
+
+
+

source

+
+
+

cycle

+
+
 cycle (o)
+
+

Like itertools.cycle except creates list of Nones if o is empty

+
+
test_eq(itertools.islice(cycle([1,2,3]),5), [1,2,3,1,2])
+test_eq(itertools.islice(cycle([]),3), [None]*3)
+test_eq(itertools.islice(cycle(None),3), [None]*3)
+test_eq(itertools.islice(cycle(1),3), [1,1,1])
+
+
+

source

+
+
+

zip_cycle

+
+
 zip_cycle (x, *args)
+
+

Like itertools.zip_longest but cycles through elements of all but first argument

+
+
test_eq(zip_cycle([1,2,3,4],list('abc')), [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'a')])
+
+
+

source

+
+
+

is_indexer

+
+
 is_indexer (idx)
+
+

Test whether idx will index a single item in a list

+

You can, for example index a single item in a list with an integer or a 0-dimensional numpy array:

+
+
assert is_indexer(1)
+assert is_indexer(np.array(1))
+
+

However, you cannot index into single item in a list with another list or a numpy array with ndim > 0.

+
+
assert not is_indexer([1, 2])
+assert not is_indexer(np.array([[1, 2], [3, 4]]))
+
+
+
+
+

L helpers

+
+

source

+
+

CollBase

+
+
 CollBase (items)
+
+

Base class for composing a list of items

+

ColBase is a base class that emulates the functionality of a python list:

+
+
class _T(CollBase): pass
+l = _T([1,2,3,4,5])
+
+test_eq(len(l), 5) # __len__
+test_eq(l[-1], 5); test_eq(l[0], 1) #__getitem__
+l[2] = 100; test_eq(l[2], 100)      # __set_item__
+del l[0]; test_eq(len(l), 4)        # __delitem__
+test_eq(str(l), '[2, 100, 4, 5]')   # __repr__
+
+
+

source

+
+
+

L

+
+
 L (x=None, *args, **kwargs)
+
+

Behaves like a list of items but can also index with list of indices or masks

+

L is a drop in replacement for a python list. Inspired by NumPy, L, supports advanced indexing and has additional methods (outlined below) that provide additional functionality and encourage simple expressive code. For example, the code below takes a list of pairs, selects the second item of each pair, takes its absolute value, filters items greater than 4, and adds them up:

+
+
from fastcore.utils import gt
+
+
+
d = dict(a=1,b=-5,d=6,e=9).items()
+test_eq(L(d).itemgot(1).map(abs).filter(gt(4)).sum(), 20) # abs(-5) + abs(6) + abs(9) = 20; 1 was filtered out.
+
+

Read this overview section for a quick tutorial of L, as well as background on the name.

+

You can create an L from an existing iterable (e.g. a list, range, etc) and access or modify it with an int list/tuple index, mask, int, or slice. All list methods can also be used with L.

+
+
t = L(range(12))
+test_eq(t, list(range(12)))
+test_ne(t, list(range(11)))
+t.reverse()
+test_eq(t[0], 11)
+t[3] = "h"
+test_eq(t[3], "h")
+t[3,5] = ("j","k")
+test_eq(t[3,5], ["j","k"])
+test_eq(t, L(t))
+test_eq(L(L(1,2),[3,4]), ([1,2],[3,4]))
+t
+
+
(#12) [11,10,9,'j',7,'k',5,4,3,2...]
+
+
+

Any L is a Sequence so you can use it with methods like random.sample:

+
+
assert isinstance(t, Sequence)
+
+
+
import random
+
+
+
random.seed(0)
+random.sample(t, 3)
+
+
[5, 0, 11]
+
+
+

There are optimized indexers for arrays, tensors, and DataFrames.

+
+
import pandas as pd
+
+
+
arr = np.arange(9).reshape(3,3)
+t = L(arr, use_list=None)
+test_eq(t[1,2], arr[[1,2]])
+
+df = pd.DataFrame({'a':[1,2,3]})
+t = L(df, use_list=None)
+test_eq(t[1,2], L(pd.DataFrame({'a':[2,3]}, index=[1,2]), use_list=None))
+
+

You can also modify an L with append, +, and *.

+
+
t = L()
+test_eq(t, [])
+t.append(1)
+test_eq(t, [1])
+t += [3,2]
+test_eq(t, [1,3,2])
+t = t + [4]
+test_eq(t, [1,3,2,4])
+t = 5 + t
+test_eq(t, [5,1,3,2,4])
+test_eq(L(1,2,3), [1,2,3])
+test_eq(L(1,2,3), L(1,2,3))
+t = L(1)*5
+t = t.map(operator.neg)
+test_eq(t,[-1]*5)
+test_eq(~L([True,False,False]), L([False,True,True]))
+t = L(range(4))
+test_eq(zip(t, L(1).cycle()), zip(range(4),(1,1,1,1)))
+t = L.range(100)
+test_shuffled(t,t.shuffle())
+
+
+
test_eq(L([]).sum(), 0)
+test_eq(L([]).product(), 1)
+
+
+
def _f(x,a=0): return x+a
+t = L(1)*5
+test_eq(t.map(_f), t)
+test_eq(t.map(_f,1), [2]*5)
+test_eq(t.map(_f,a=2), [3]*5)
+
+

An L can be constructed from anything iterable, although tensors and arrays will not be iterated over on construction, unless you pass use_list to the constructor.

+
+
test_eq(L([1,2,3]),[1,2,3])
+test_eq(L(L([1,2,3])),[1,2,3])
+test_ne(L([1,2,3]),[1,2,])
+test_eq(L('abc'),['abc'])
+test_eq(L(range(0,3)),[0,1,2])
+test_eq(L(o for o in range(0,3)),[0,1,2])
+test_eq(L(array(0)),[array(0)])
+test_eq(L([array(0),array(1)]),[array(0),array(1)])
+test_eq(L(array([0.,1.1]))[0],array([0.,1.1]))
+test_eq(L(array([0.,1.1]), use_list=True), [array(0.),array(1.1)])  # `use_list=True` to unwrap arrays/arrays
+
+

If match is not None then the created list is same len as match, either by:

+
    +
  • If len(items)==1 then items is replicated,
  • +
  • Otherwise an error is raised if match and items are not already the same size.
  • +
+
+
test_eq(L(1,match=[1,2,3]),[1,1,1])
+test_eq(L([1,2],match=[2,3]),[1,2])
+test_fail(lambda: L([1,2],match=[1,2,3]))
+
+

If you create an L from an existing L then you’ll get back the original object (since L uses the NewChkMeta metaclass).

+
+
test_is(L(t), t)
+
+

An L is considred equal to a list if they have the same elements. It’s never considered equal to a str a set or a dict even if they have the same elements/keys.

+
+
test_eq(L(['a', 'b']), ['a', 'b'])
+test_ne(L(['a', 'b']), 'ab')
+test_ne(L(['a', 'b']), {'a':1, 'b':2})
+
+
+
+

L Methods

+
+

source

+
+
+

L.__getitem__

+
+
 L.__getitem__ (idx)
+
+

Retrieve idx (can be list of indices, or mask, or int) items

+
+
t = L(range(12))
+test_eq(t[1,2], [1,2])                # implicit tuple
+test_eq(t[[1,2]], [1,2])              # list
+test_eq(t[:3], [0,1,2])               # slice
+test_eq(t[[False]*11 + [True]], [11]) # mask
+test_eq(t[array(3)], 3)
+
+
+

source

+
+
+

L.__setitem__

+
+
 L.__setitem__ (idx, o)
+
+

Set idx (can be list of indices, or mask, or int) items to o (which is broadcast if not iterable)

+
+
t[4,6] = 0
+test_eq(t[4,6], [0,0])
+t[4,6] = [1,2]
+test_eq(t[4,6], [1,2])
+
+
+

source

+
+
+

L.unique

+
+
 L.unique (sort=False, bidir=False, start=None)
+
+

Unique items, in stable order

+
+
test_eq(L(4,1,2,3,4,4).unique(), [4,1,2,3])
+
+
+

source

+
+
+

L.val2idx

+
+
 L.val2idx ()
+
+

Dict from value to index

+
+
test_eq(L(1,2,3).val2idx(), {3:2,1:0,2:1})
+
+
+

source

+
+
+

L.filter

+
+
 L.filter (f=<function noop>, negate=False, **kwargs)
+
+

Create new L filtered by predicate f, passing args and kwargs to f

+
+
list(t)
+
+
[0, 1, 2, 3, 1, 5, 2, 7, 8, 9, 10, 11]
+
+
+
+
test_eq(t.filter(lambda o:o<5), [0,1,2,3,1,2])
+test_eq(t.filter(lambda o:o<5, negate=True), [5,7,8,9,10,11])
+
+
+

source

+
+
+

L.argwhere

+
+
 L.argwhere (f, negate=False, **kwargs)
+
+

Like filter, but return indices for matching items

+
+
test_eq(t.argwhere(lambda o:o<5), [0,1,2,3,4,6])
+
+
+

source

+
+
+

L.argfirst

+
+
 L.argfirst (f, negate=False)
+
+

Return index of first matching item

+
+
test_eq(t.argfirst(lambda o:o>4), 5)
+test_eq(t.argfirst(lambda o:o>4,negate=True),0)
+
+
+

source

+
+
+

L.map

+
+
 L.map (f, *args, **kwargs)
+
+

Create new L with f applied to all items, passing args and kwargs to f

+
+
test_eq(L.range(4).map(operator.neg), [0,-1,-2,-3])
+
+

If f is a string then it is treated as a format string to create the mapping:

+
+
test_eq(L.range(4).map('#{}#'), ['#0#','#1#','#2#','#3#'])
+
+

If f is a dictionary (or anything supporting __getitem__) then it is indexed to create the mapping:

+
+
test_eq(L.range(4).map(list('abcd')), list('abcd'))
+
+

You can also pass the same arg params that bind accepts:

+
+
def f(a=None,b=None): return b
+test_eq(L.range(4).map(f, b=arg0), range(4))
+
+
+

source

+
+
+

L.map_dict

+
+
 L.map_dict (f=<function noop>, *args, **kwargs)
+
+

Like map, but creates a dict from items to function results

+
+
test_eq(L(range(1,5)).map_dict(), {1:1, 2:2, 3:3, 4:4})
+test_eq(L(range(1,5)).map_dict(operator.neg), {1:-1, 2:-2, 3:-3, 4:-4})
+
+
+

source

+
+
+

L.zip

+
+
 L.zip (cycled=False)
+
+

Create new L with zip(*items)

+
+
t = L([[1,2,3],'abc'])
+test_eq(t.zip(), [(1, 'a'),(2, 'b'),(3, 'c')])
+
+
+
t = L([[1,2,3,4],['a','b','c']])
+test_eq(t.zip(cycled=True ), [(1, 'a'),(2, 'b'),(3, 'c'),(4, 'a')])
+test_eq(t.zip(cycled=False), [(1, 'a'),(2, 'b'),(3, 'c')])
+
+
+

source

+
+
+

L.map_zip

+
+
 L.map_zip (f, *args, cycled=False, **kwargs)
+
+

Combine zip and starmap

+
+
t = L([1,2,3],[2,3,4])
+test_eq(t.map_zip(operator.mul), [2,6,12])
+
+
+

source

+
+
+

L.zipwith

+
+
 L.zipwith (*rest, cycled=False)
+
+

Create new L with self zip with each of *rest

+
+
b = [[0],[1],[2,2]]
+t = L([1,2,3]).zipwith(b)
+test_eq(t, [(1,[0]), (2,[1]), (3,[2,2])])
+
+
+

source

+
+
+

L.map_zipwith

+
+
 L.map_zipwith (f, *rest, cycled=False, **kwargs)
+
+

Combine zipwith and starmap

+
+
test_eq(L(1,2,3).map_zipwith(operator.mul, [2,3,4]), [2,6,12])
+
+
+

source

+
+
+

L.itemgot

+
+
 L.itemgot (*idxs)
+
+

Create new L with item idx of all items

+
+
test_eq(t.itemgot(1), b)
+
+
+

source

+
+
+

L.attrgot

+
+
 L.attrgot (k, default=None)
+
+

Create new L with attr k (or value k for dicts) of all items.

+
+
# Example when items are not a dict
+a = [SimpleNamespace(a=3,b=4),SimpleNamespace(a=1,b=2)]
+test_eq(L(a).attrgot('b'), [4,2])
+
+#Example of when items are a dict
+b =[{'id': 15, 'name': 'nbdev'}, {'id': 17, 'name': 'fastcore'}]
+test_eq(L(b).attrgot('id'), [15, 17])
+
+
+

source

+
+
+

L.sorted

+
+
 L.sorted (key=None, reverse=False)
+
+

New L sorted by key. If key is str use attrgetter; if int use itemgetter

+
+
test_eq(L(a).sorted('a').attrgot('b'), [2,4])
+
+
+

source

+
+
+

L.split

+
+
 L.split (s, sep=None, maxsplit=-1)
+
+

Class Method: Same as str.split, but returns an L

+
+
test_eq(L.split('a b c'), list('abc'))
+
+
+

source

+
+
+

L.range

+
+
 L.range (a, b=None, step=None)
+
+

Class Method: Same as range, but returns L. Can pass collection for a, to use len(a)

+
+
test_eq_type(L.range([1,1,1]), L(range(3)))
+test_eq_type(L.range(5,2,2), L(range(5,2,2)))
+
+
+

source

+
+
+

L.concat

+
+
 L.concat ()
+
+

Concatenate all elements of list

+
+
test_eq(L([0,1,2,3],4,L(5,6)).concat(), range(7))
+
+
+

source

+
+
+

L.copy

+
+
 L.copy ()
+
+

Same as list.copy, but returns an L

+
+
t = L([0,1,2,3],4,L(5,6)).copy()
+test_eq(t.concat(), range(7))
+
+
+

source

+
+
+

L.map_first

+
+
 L.map_first (f=<function noop>, g=<function noop>, *args, **kwargs)
+
+

First element of map_filter

+
+
t = L(0,1,2,3)
+test_eq(t.map_first(lambda o:o*2 if o>2 else None), 6)
+
+
+

source

+
+
+

L.setattrs

+
+
 L.setattrs (attr, val)
+
+

Call setattr on all items

+
+
t = L(SimpleNamespace(),SimpleNamespace())
+t.setattrs('foo', 'bar')
+test_eq(t.attrgot('foo'), ['bar','bar'])
+
+
+
+
+

Config

+
+

source

+
+

save_config_file

+
+
 save_config_file (file, d, **kwargs)
+
+

Write settings dict to a new config file, or overwrite the existing one.

+
+

source

+
+
+

read_config_file

+
+
 read_config_file (file, **kwargs)
+
+

Config files are saved and read using Python’s configparser.ConfigParser, inside the DEFAULT section.

+
+
_d = dict(user='fastai', lib_name='fastcore', some_path='test', some_bool=True, some_num=3)
+try:
+    save_config_file('tmp.ini', _d)
+    res = read_config_file('tmp.ini')
+finally: os.unlink('tmp.ini')
+dict(res)
+
+
{'user': 'fastai',
+ 'lib_name': 'fastcore',
+ 'some_path': 'test',
+ 'some_bool': 'True',
+ 'some_num': '3'}
+
+
+
+

source

+
+
+

Config

+
+
 Config (cfg_path, cfg_name, create=None, save=True, extra_files=None,
+         types=None)
+
+

Reading and writing ConfigParser ini files

+

Config is a convenient wrapper around ConfigParser ini files with a single section (DEFAULT).

+

Instantiate a Config from an ini file at cfg_path/cfg_name:

+
+
save_config_file('../tmp.ini', _d)
+try: cfg = Config('..', 'tmp.ini')
+finally: os.unlink('../tmp.ini')
+cfg
+
+
{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test', 'some_bool': 'True', 'some_num': '3'}
+
+
+

You can create a new file if one doesn’t exist by providing a create dict:

+
+
try: cfg = Config('..', 'tmp.ini', create=_d)
+finally: os.unlink('../tmp.ini')
+cfg
+
+
{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test', 'some_bool': 'True', 'some_num': '3'}
+
+
+

If you additionally pass save=False, the Config will contain the items from create without writing a new file:

+
+
cfg = Config('..', 'tmp.ini', create=_d, save=False)
+test_eq(cfg.user,'fastai')
+assert not Path('../tmp.ini').exists()
+
+

Keys can be accessed as attributes, items, or with get and an optional default:

+
+
test_eq(cfg.user,'fastai')
+test_eq(cfg['some_path'], 'test')
+test_eq(cfg.get('foo','bar'),'bar')
+
+

Extra files can be read before cfg_path/cfg_name using extra_files, in the order they appear:

+
+
with tempfile.TemporaryDirectory() as d:
+    a = Config(d, 'a.ini', {'a':0,'b':0})
+    b = Config(d, 'b.ini', {'a':1,'c':0})
+    c = Config(d, 'c.ini', {'a':2,'d':0}, extra_files=[a.config_file,b.config_file])
+    test_eq(c.d, {'a':'2','b':'0','c':'0','d':'0'})
+
+

If you pass a dict types, then the values of that dict will be used as types to instantiate all values returned. Path is a special case – in that case, the path returned will be relative to the path containing the config file (assuming the value is relative). bool types use str2bool to convert to boolean.

+
+
_types = dict(some_path=Path, some_bool=bool, some_num=int)
+cfg = Config('..', 'tmp.ini', create=_d, save=False, types=_types)
+
+test_eq(cfg.user,'fastai')
+test_eq(cfg['some_path'].resolve(), (Path('..')/'test').resolve())
+test_eq(cfg.get('some_num'), 3)
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/images/att_00000.png b/images/att_00000.png new file mode 100644 index 0000000000000000000000000000000000000000..7d44d3f43f23d4c14d83efaaed0dc2fbf100b55a GIT binary patch literal 35850 zcmeFZcQ~Be_cx44kQ|W^adeXCL85m;5{Vw7x9Ay+-rGb7L4t%3okZ`wGeY#}Wth=B zW0cWn4A1R+ePmXut ztO)Rn7YxE9{OcJHj}`a}G?j|~&(~CfzrS8sOug{;Grr1M!QAD}7@!ed&~qIZ9c3jk zGkY+PiMhS01&;^V;j93jgohaL2)1xBVe$am+Bu7PNZ$IZgc$IA_L}z=(_ckgY$R{# zD628a**jS<3Gv+HxpzzIG7}S%gp;|YnEJ!V|5Y9MPx97F7Z(RHUS4;1cOG|s9(yM% z-ut4WqP+L`c=`CaffC%#o^~!K9^7`$xBt_~-|alKa5i%SIkHmH8Hh!b&#U=nKmVcA1!Vb8Pj=4#H7sC&yk}o{@AKT_{n<89RpRWen5q-V0_gdyeX08rf0aD< z?!Wqx;63a77h?W1(!bsULzTKL!TXbKQkSWXW{L3dWbmFoeDK@@e?5sP@y4T};4pUG z2jBBkKRe?&%RWcops;*+C-h4;(?`OKkJL)jv6$&G zP^-Wcb)Lic3g5?Vd2`Eb=XbrE`9<+COmv%89ah(ukikUv`|U)ii>^X z|I4etA3X?&7hMSdRsPy5nQ&sJ=w)JwR@rk6oz=S5wR++2+CRJTr@Jo0-gn(2^v%ys z|1L9pyxq>2_8Uz=A6JP}Ir{KjLIZ!R^H!!pf=UMe-{S!4j8n*H814Vyxc=+-{_1Lm zgeiLH`tO4mz4b~h`S#Y0E5EgtO+xUmfm=M7soQMi3Nz(Yrq;J_aQ(tvteD!dA|Gw| zn8fK%5@pY;vl;?_bM@~5J_i%L?8@8U%i8<<%^6$Roe7YIb#`&Fx*sklO8I(qtu^zo z&_Hg{*X?pRyWdpy+!)i~`>iQQKpdL&7y5nvMcB0tdi+52L`jzUzdvNp0TRjcAWA*@ zwf8gGM~V}Ocy-fzD+Hb6uanYD3go23b7yJ%Ba5P`je4CM*k-Iat)R4vvt(J6*#9HB z3_CB!gF(4-qNj{`MTk!E!*re;@AQocQPni2$f;Hs7teQ zyE~x1ULsGoEK^#$%Fgh#PT_TT@c{86_3K+S=eVVIMBE`@7{BE@s@s0^uFi`xt3Dx= zEAC(#qTSebv+NOh2Ly`}wpYFfIq}IeYN#zJX`>lUe@YR>;{WGzEY>62ngE-jsa zOQgp&6)+=2!YNhR3g?GE(&`lqENMu7(H8&Qr%WU9+r?V-S_OKQYq@!P?`Z_I|c_xXOyQg0Gc_o*3A9s#I_(y})ZRA$+OmaVyal}6BdA%ZAv^7I>| z1Q3^5iNm#X`kVa+p?U!|nN2H8q@o;;zf)H<$JDXjvWo$Y^XoW52T%t~B(h3s@GY-V z{TSr?ljHAtQB0RZ^EydeS<=}6^-dyZJZhhgQKr-1Xqz-$M zM2qpJ8R*SSLrxnAswBKMV}%S@k)^EH_(9DUk5cU&pGRI}AarUSk_WwJmGrL2@eyT? z)^4;>2s<~e{O=HucT~95gN8Cs-Vr|b{V2FV-a*Os8N_Cx!E!qM@Xcr>5vk`rBy4&v zJ$0Hn@KAw*^+B^}Il4jPElo8ZZplQHCNKra&(v*+N4JTjom@QiZ&~ndg29l z90P(KPvt3(RZ+1T!n$NY5gK&rec0x;bb464k7yr-O-9bzIzfWVH1Xog&N zM@kTqHe#3B8k>lVVEP{*O`l2h#(ki=Kv-s0VraMMjdmkz9qnPlsq_1q?-E z!Zrnwh5N-(h3o-wHea%N%YBrLPR z6>4OKSG*jMl`gQGtTiImt}o3`;H`gqy7XBRAQLYzBR&x`2K{f)dBYb$ejM3ULjdP1L(t&6vhwItrtV}Ms zf9V7(mtKsY{AoB}?0gllzKknA@Y~nUsTe--b2kFGoW86@ZmKi7jfWTYpjwHtDwjT17jh2=vj;V` zKD~L-WU?W=Cq;UCQnw zR^f&8sv|Na^B8s>o75c*@`%*yWcqDS*{Sjz3^?w*Lf$6z?ElijC*55Qz1B6K?eNDr za@Yk4ENXc4n$t$#cJq6%GTTOJ#kl@RH)2-dS!3DUHJNqoK_>}bARg#b(dXA`0_d9(SJO+PWs!ZBf$hCXoC*7%mt!fdjGFSnOVaA zXsX_~f1X>#&S>ygXMUw-#HrJHr?_W3pd!TrcEAID=)@5L2HxjvR zdVV&ab*u13rqQ=+C#I-)Q85M{YSFEbagXnfOeSG2EFUCj4J)-4{4CrRO}%|iCjO!F zOeHMwgy@VbRGRfS)#eqHQ?(juiI+ZME)R*ETamy7B!cMz3xvec!UVhBXtzh%Wao@; zq%r|X8eP<$ttm^9?e$b+%dk5~=gD0BAS27p8}aF@%I|#YQo>8C=QB2hU-~zD7vu3{ zJ!={zo}XXGfgyA9`}^pB(Oe1|6#A7?pi@f!rdHn|c->bBhuR3eu(dT=N=24nwnko) z=+%XorsGyc)Vlm7gf@j0Wp>9m@qBxC*Qtu8Z3jR}n7#?08`hZ#O??NbJg?czjep6W zNrND3y(|P=Wj5D(`+n{=DD?Rgjv7tFJ|8?CLgvnOrUSJ@&)2g(z$ zR+|~Jj+nGPR(;c_@CUV6xePqg_}~g}@uRStEUD<3vwzLy2-92nKqUIZzq7fbOixZrVxvOt7lBZeL*2^(*m0L?#G;~PIS}<2zQGY0- zTYHRc8fVS>$H{o(sYQ5?e)({_y#a)BsCK^>3tmIpSo0vq?rkN2+-9SUG0tzm_(D6I zk4CqXBT!YMSHP&Yz4fCo_*i`2sPY1~-+NlW$h}>!rM6wn{yW>|380Jx5?+@)P4mcG&c3W#qfImPKSyfEXplvS(qHRCiVf?pPpUfl``IY1u z|7j8yd$&(JmvBIOnY)rKNi8R$zG@m_Au>fK52qW{7{a*^t>O$%2id)0_n%?E zKJaOD1WTNTFoSg2rwr}imrzZ9|Bj}-xN~T?MyDNXlKJ$)_Jm84=GWF6SYcVul7SEB zmO@~CwIhC)yqh&SyvfBIsd%N)aA%|d<%Wc>ks`-FW^^ZwVui8C!PE6i1_)=vgE{s( zD01VXKsR}{w}kYqG-`XbteC#6J=PxEGzu5#(-UD@KD*35tA#$uSk3{&IwGm8ssQSR zQ@207#dhbwXOYWTn53zFv!o=i-O1bR@CLHK*7FPZ;93fHj4Bhu@z67WNdPxk4B6^& zNq~CfgtSsONLNWs9+YIhU%LZmQuL=aVz9u;D{Z%%gZrIOk4H^nmy&Y^LF5mk=%XMh zR!QEz)?~>gSyhjpn5+L_WErekuAzSWG>UC}Pk67q;lMs>%e=AM$b0ORr*1gtDx)Qr zR{j%RK~G`GX@I|*`mzQ%s-SXr6*lGIiyT|M;ay`atzTR`qomyRgL5S$o9c+l$gi_% z?#yk1VGpWWBGz6g!*sj9FZ^(>9sg_(6}+!X>9W!8IKN(+S6B{qgEN0CYjJFcYxGHg zotJwQKMmW};Di{Br!VJfZ^|>4R0fwTE;z4&3~hIXjkEFt)_6Df(4j@Umo+j~I<-?8 z;OkZq5+@#?sw)}rPJgwHOx=VrqWGnKZ1d|y7ZsKC9Vb1Sdq)qBarsgF1yZ(Ir0dy+ z`ePTeHtkehr(s&onbVi$l3s|JHY=nFK9^tGI6Y_+Ch;=Pn==I017YLP8 z988Qch&iizHRN zuRlqqHbX^&uLFv?@hbUP>q$J-WB6UGTgHQGwrM_7$4734eY6E58+GFar|xy6wD%>R z#TG%2+8BJQtCHLY-U!Vur%<$im2P{_Xy2ab@w!49!;Uum?N4RxaY$GThsvSkY;=_EOfchTk+9C8zWs`?sv=WTr*mOCgyah>4>xP3 zrQD2*h{*MuIZ)!84K`Np(y)Dd_tX^jkRB!{wI~kMRq0`#`UO*30gqzouRca=2cZ>` z)k&u+!lJ2!-Lc$djeXKqbsH5{jhH_eMVot1r{B1Z2x{N{EdP0j;#Z>|NB+6aAqTfU zs=}2&Ti#G--)On6XJ5b}ZCUkxB7R*n|4~^`+C09w()X^@~B1p)DX#mUV9Q< zw3e*jJ^k2Mr;CSiodXJs_9Pui6JGnzZK@$h&W%GailSL6gb%q@@L)8D3rsyHr0tvL zt~NyiH)G$t8cpPS`Q?Gls>Obxgcn^y0IF^Te(|$44nwITGVPA6@D(FDuz#sF4h&yix_l%GS*%*P(8)4GV+e!y7g8D$~M^r(W-pAa?F48?)^UWx_;% zJc%P>JHLBsCV65e?rCWqHg-zi_}_CB460HH1qUtaJyJf%0V- z<`nOd!9k$n=|82$MGY0fl=Oq2cJ*m6dxM|5AcBrDxa|XlSudjH{zBJoOOCMU5GX6B zKuvK7zp`EDf~&?-S|`3}U!I0dMu4bjK$Nb}Q`rx&Xhk{9 zTsLn*Am^KI-kM=wo)XO7iM~cEs!M3vmLKVHOma~v$)a>B??8_AJqVekKi<;7P+m|u z!8dRzW74D!1;(N(%QmPIH|He}=B~KyQECH$jU!1U3%TY;#)An+O3J(H#kS-NZkx@4-#RzsT2=Mol+sXi`-DytqJNAhb*!?Lde&UQ?a1G>{Fn{lfbQMsq3 z&(ihuc^mFe3G=t7FS~1qHocoFCrrb>uZHnf_cvnw@_mmx*@Rri)R6rr#CaOa&Xa1 zqk08};D!ejr{a?kaHVd$_=BixoXQOX`+QWqJxoRGddtb2KB&=AqISDFaIK|jlBa;{o@M`NG`cTQbO_UM5?|Ce zKriM|;P#w}jB=!kuw`vzhibc}ni0j#*3aQ0wKwcTkRZKsq9I0Nla=ffD!tp8l`^(# ztlc{oDDr6!8>+}#cBM8Y_F9LWc*d$-&34-qpUGVM)7fHfcYB&9mK3zE^{t}7PPCMM|sg+<{idiF8 z2u0(nT)pcz^Nj$e9Ytat*4#(ICQ7mY=0y0M^}!>EyB=v-x8s+Pm{Iga2VlEiE#A7h0T2P@UnFm#v#pr>JZ~j13jCvc92!40mQ;-^+ z0Ig_TjGHIg@ooi8*)GO!Ki{4Yw|V{GuIwS=KJ|>!;E?Yn(Pej&Il11gg|x;yX%6V8 zHKz-sZxy?993}?Z_2x&k6hl9p^gT27wcxk>v9&bjjViIq$IGEhXR#~WZ1e+TVq1d7 z%U7ZBOGx`jsh!Jyl{U*fqp19{%fv1I@(o^lm&+Y`jUnS5&%PdSgDa=RQd(sNN?FC? zh3z-UaEpT-fB2$a20|c=-n;ilPl{ViixekoU2#qq9wkY5h616fZY^;6;H;bg7iieq z$i1N|<}CxvURQkh5r6W#H_%@_bG17Jd@YT6Lxp~{#VcBt@GPIWaxHk3d6NM>>OWyZV90)ai%3p-R(MBFc5m@javEBihC|Xw-e^sIC>gJzs$a zdd_gX#S2-Opq@Pn$6hz~S%rn9cuZ`Q+$c+m-J#~UI)w5zpf7LY3>f<7rIJ)P*XBFJ zu=&!bN(U>&fkFP;aS1TWAx@Y2bQ9*+_rE2+~q+;Q!AYJe!U; zlA7!i3P2aU%FCvDwm&r~@-(K&_iMHvw7o|j=(N1+l!LRJBg z&n89U^0xC39D-5f$|A?{J`7svUAwN;6jk$M!Xn7<2DoNUp(VLHwV-qNSw~Qto(+r< zRT&H3q-*|U!CtDyAdu0Tlb#qZXg47;pYD7TZ)QS{$6V@Qt15xc?lcp_|J9gZ%l0BP zUn>wC!z8Xt1oAq(-k00-wO57kO^M4zX_Pn8}*hMnir;*gHt%5t@AYxC=3ub;}?VNz(inZ zqdOdM@P{5QHx=f;LElO!Dym%T5?tW(Ke2%Ga?sMc%VrKds7^k@Dq;EGkhng{D}a{o z>)J#Q#mNO9YHsUGXk*({b+6!&5~t+{=)R)-49sQ_GKv*IR*XHlO&;K?mWQG*d<>>EqkVU&|SY`cSOFW!w zj|&l;pe-Eezfw7Cu&Zy=)1tSzvc2WqMkh>C?6K%(KC9yhbsxV|$~CeeJ!ChODY#+= ziJPY{Q+8(4>^uRl5xAa!{VZh1*bfL= z3nR=mAX_`Umk>ZKC`MZL<|zib2?duU_>>Bfd-ohfAeeYZ)T#L{ z)_Ka5c7JFyrnkG64$AE`HBM>1#;^~I(I}S`GVW%Ky@nZXpI2rW(RlMzMe$_mEyqc@ zQX9gqs<88l4>5X%L89z*EpX$xXQze_l$VXA^8S_8Fl>W!x1g54bR=28qRNV-G2b;*;d%D;c3fKD?P+*>tkE^#s;RcC;tOgiCuzZq``$)u zl(Q8LIHLN+eK|;Hir8UlK2=CVCs9;Ny%WoclRC*;*#>|4!7&N9k)_*&g;ODZtT@E=*=6u*@doau@aKQ zcLF)r>m4;Vb$U;?Hz7z-=fmPQ16Qv@+@|uPd;lR@90Q5cT6y2rw{U>T6E2o>GpJFF zC0wvEq61BHX%wv^kx7l#oh|oAT zk7_dfYN;GGUQ<2;7ek>Hd6aFxW`u&2y_Pjp90?Yzq;Mtls>S>&$hE3j>#^bw%83F4 z$=sK-3R*5F<^v+8DLQkU_`+dKd%tF156kjEZ+ZWOCuM$03#!ry}w$iZS`?ftX}|E0sn*bIwB7?M3dF_D+sohb8UD%XKAYlMGu) zwndWr_wE~Rz(xF;32AYAFTJr1?gdeZQ^~b&lJMkh3cpg`;Hwq%Ze!oH^j$UkR$<1F zim3=m>xk-zX5Fk5I|R54EI@tEkm33B-BQbPBNac5EI>`H1~gp5oxp|?)g-(3r`_lg zX^%9Z!TSfjN?0IzLcsvj&ND{TRv`FNg7^25UipoGKSP!&~#TE9@Wb!21u02{*yfyqx@mg(Ir-|)%KJH<{b z@he|uFLz_zl&`egfFPj@5(4)Ja3#F?i}3gPEj&HGIF@0kEMKF711gd0Xy| z(6GDFc}#J|(~v&NeW)UD3A4&8@0@9_lPH4_aMd{LQRFGMKY*-6o?#uVZ7|u=cDfq{ z;^OuF7(m#AENm2VODGmjY!kBG{*$xxHkR`dO{;@>zJi#~km+9U`cxz^($EJV+8jSAq&UtPU|3+K*bTW< zG5dn;iSZ^pb#H&*8oGM^z5V(~T9gk1+6aP09wCbaoU+|9_z4J6yN_~;1PU~0SUPbH zs(5mLU*)uFJ&ZSaOtGlmR4$lohoG{wpJq!4i?V8GaCI@oc?uxcM)DBA-g=Co4rR&P zh%Rk7_$EUu>XZ(9XCu7<_^mS)^9Am97NLsliA^-U+j^TsUY`C(i+;Fc*CWjI-ZX7K z)W5>6qDtj-73fjx$bM8}~RyIhb1&fm66E9?zQa8!3wm~L! zow$75lAhKB#k}71z+Fc=B}k$s2rX2I>yLg&& zK&%t`*pL-VjvfheP0VsvHg%b(%Q!G%jFoo`*L1d=m{RxatRF^3hDF^6ao+UTw}bZB zRUffJqh|mwo}XKToj1*`_U}(QF-XC zY4uz8`s2Ed4;Nyk+?7KoMno%G1+7=qYl+Q&PrzV*2ZZ}g0!7GvF&qDRWM?60HPSFr z*vq*#-fLW(+JP-&6V9*qa#Ag1gPc!H0HT?zK=KJ-)3M%?GcaSS+n`%dJ@*!pvzerS zaS8!^CXwRL#Y(X&h!29G;?N4anjjFwR`%#t@efp|lut9`UlDv$I04TPfT(kD%>5d8 zJ4@&=Bk+~Ray*+0rxmOKPmUS`A$|&_uI`9d#aP7IzRy@WQFDQlIhu+(?g-cW)jOH$ zc9>J_LsX6}nA1Hn=i09>DnQL00^5)n!a(V6M*PZ$To70w&G`<;nVU=l*B$Oq{mS;g zKo*$~BzFSQYl0=_ynK@6(PH=*i=5k;c<0J71rw6XdcKEOIO&jv2FXYOWhAJ=&x1^# z0%S~;YvQApC#rdkONX`Y>T8MW$#Zeu#Xn0p&~7O+f71~3obLS2Fi}P-t$u6e`}v*t zUyNqbCnR4&j(0`+oa6g{B-(K%YsNg6+H*_`4OFAO?h#f>y10?(qx&Au>8tDpT z@k2_{SO=e8#V%JHu~Ws^ZD5ZC>;|&Ajvq#TQ`6If&|p8 zEIj&;U!C^IQ)N`6;p-Lt$K*L3q=0qXysG=2DoSGZ`$J^Q1}`i|g)qdagRT@>q6CHq@NFtJIjX!Y*gcIL1{)Gq}r1 zLLc@}g0tDR)6$zukujD2r&gxs6F>JzGoW!IAmn3-1VK6lj4~H3$&1o0Vg!6yUGuFS zOTP)wdPY+ogg%Frn#zj)Q?s1pubK@1FKgD9JK&sf+$S3Gs$306AZi zNj#s*aVFL1o50i`yrtMk8QSzCjvv)=JEEMwPhtqjDN{>ZQ?XzMFjXLDrVLdzJ!J>Q zx#79SvuRK~x@cwoTq`38YQU9uV#UB9@IQ9b1%(oV3m}xp|grRQyFvU+ncP^#O3SmMY z{v-CWrweq8K)?Luvo4oJb}9cF=VkcU2r28mwUM%LdT~7QS0|* ztw(seoXW`K8ybz~e1?2^`6t8Kr2&!^SM}CsM$M*tTHc>H?|sr9UrGRLy?mONUm98= zyPec)*D#PQ4 zlds&Tcm&*)*Z2H(uiJP(5l^uMP`UE5x)d8Aab4&StuCX z2>)f3kB-E%{zguq^yzpe03IiGnTDN=R%*iXM2cV21yb*?-|b@w8=`Ow`h$LrXe{Ky zaR(>9sEhafdtsks6rxI4IrJJ+q$0uK;|N;mDF$yeiT6n>mF<3_Xrman@YI;l#EX__ zO^sUKNxpYicp5v}e6R)J+D=wCnFJhojaLJeW0hPPF|jZ-q$&YA+roEA%&FKGf4k&1 z<4>g5mn?|_m|a?ESl9Mw{?DJBd?iByB*F6HOMKL_B`{0c-vSaC58|7+t0qcKg@fR+ zocJUedRB(f5ra2a?&?%G@zm~;BML`Ugn+QedMyKNY)AEAPdC4;S8UW}Z$!hA&A(m) zHe|a!*Sg=vg3A=8Zw;3!eK6xo=5ZxyZA4oN zzIc0fOOC8;(rvOQp}6n!hbcX_!dExB^~O}hQRa+(hiSg2xC6&$BEKYws1Xoos<6jq zuC!_!RsM~_7S#=7y5$)l5*asFBXrBwr-(MH00eb;o-1h(It7K|cKW1QnoW8aM94>V*KRl=>Orkf?I+I*|^gXDhM4R-MOb5>*;$gb!vyYUx{*o~$7 zgR4-LT3ITF&<*tQso_f?d$yb+LR^Y*HmxOi+>^@ivwc$Lr7S+)k>zv>m2!lA&B*9W zxPWnO=x%$Fihh2jfzOeJP&dgi!nW)^j7b`2Ym5aotBx*jv!M&DKFREK3E#Mm4Zol+AVJ+SF<~IuZrRl%ky`C zigGU2YLjfo3wSJSw<->to?AOHzb8pd>@K5vQ*kuLw?!lL?+988i=+@nanF}XuGmt zCH`PG`2O^`{3huxlBePXotM^9a1_+DGw|^m`?rV938NO_bbQ0@jJpHv`}3de8{$@+ zRjy=I#1CH98r}+`h!IQn3ax;Htgv2(PiRGE=xH%WFDTfQUpy%exl~|`a-6Ifb()Xa zAGIk$fQ2V*V~w418ZdK;`@?1t2r}uD7s69cQJwihqCV)=EVnmiUKo%e_(%3YWBvn1 zzx9ivo6(#-wXmVOB-BN}f-)SstPi*6jau}p{Dz^`ImNdhe@D&#F--BOij}cVJXjAQ zI@<^$VSWC6ZsH0LJ5yxV-Ri_d0FZnl%cTA3&V=Ogm>B?}(b3Kdq? zNFHaN0szQ14bEJU{3?W>-PqgfMjE&n{jbMPQ0?RGo!TTb?~M}qTZTe@5+}n^M}+9e zEX+6(H@y|V;*c-lXEXO?3AvhBubeC~u1~mL-V$DUft^5s=_Y~gXIU!SiPU!G1COOPQ<4_n(cK~cWtUnipV~#dXfIAWu5V9PT$ofh#w}^z zl{G$!=`Kk8S~NK^Dm~DDT2NK5<`q8Flsved?lV=R4@Al@J_Ti``(Ck;{<_N5Wlwq% zA-<$jx3hm*CI~Ya($;T&j%~Sm0EN{tq&O_`V-BQ2>h{%3@b7|=u$}qDoFYPD&_Sl^sUVHycAZ-Rd=xq5jmieL zUB#AK`hBRyz?y-t@`zy&^v>MPeYw%An3p|ZM`c*X>PX-_9rg~yUhrn4{f=c%C1k0$ zYB~#NZQqE|dkr#iI^hQ&F>BXQWyQD0E=YugSip)=LYN>dN@bYgl^w!rt zoo_qJ)i{_I%Cw(P-$X}5MlS0L`h%X)(Z^vEz!$vcCEe;g982Gw;;e8Z5 z3B)jzseFKRp@isLp&@4ll~l3*_c0NnhchFdJp7fHKYU&IDOwnMnD4vKmX zp~>H{D#v>$rUpcaOc)Q5P5Jhz`m7%9B_yy9NG1kuK58Y`RS72 z5scq1R>ys4IPS7gar(SlH*`tSK@ZaKi8c9+ra<}tlhlaTL%6oYA83m;qhZNcSMua^ zlVZ0FmyMaZ^fKYM-`fk^H9C%P9v2>^yGn*?Bol51k7rcmdMe!-Sx#rU#>>SmtuE>rH7|7(ptj;Q8t12uI?K{2G^|}n@St1DCl>%!0J%IK zL{5|+h+O}1l0L=Bd;)g*NP6%b35!NdW?a`YbgdZd5He0S!4-_g z*laG246WlQ@tRQL3J~~h$Cclv-x;aNK6X5A0qCM5P_|&(k zVV_gIqFFui77Iog?UVH(d25I8RGX8{e!zzeeu{$DXrFQj8G;@}2Zc%w7+|QoO9`fX7K&@V?!;^1wS?lBiyNlo&^x%XZ!#8~`#RsvY) z74kV?$xwuCLxu3{aB^cDu?e5@v`<-2L(|@@JY%buHsk4#2lhCO*S5;gz3lzu=rc{` zm#C`I6~EIKvZH$U*m4y5mSk6fW-N7e;>ssC9dA?x&dqjOOkU5#*YjC-G|WAYkgJ0^ zw(^k%q<@g;4Rq3IWfO9*fAa#b#(XH99}XO3e4$Y2rD$+s5NJ+;VZXvPd7ns?GTj2Q zy%^iz?%rAhq=Bt(AU3zUpQgKR&bmE{EaPj25L)6yyY1ya_jV?*#=Mp$Jo3D@{PMG? zbEf1#R)n;RC9Kd7(Y$h`1mT(vp=Qg?zRdxz?32DOu|44RwvF zCzsyp53n=bg&;5;>2B)>)84^g{MbP{w+?2h9y3*`)k?Ls6xGkM!K*g*)!*Wz`u3B@ zH44PZjx=L7XAbTB`6V0ogOK&9HwB-L;u$qJb>lGO2Fp33QK^S#IZ;(&BAG4ET5mG& zad3VAV3uDjeMDyWI!)vO%)scV_2C2T14f4}z^ejL=x02;U;`wUjGnA~B}e*&skb@z zNiHkDuLwH1!nU$3Mwo{;A{P!9f}8SBw^az~^z}+)>BG5a1)ez~=-m%l6ManO-Hqwj zxG(og%_~8au1+&}WNSBi52j={pMoGxaR*t>=uE5U3BLP#I92cOHec=rp5?rHp4N3t z`JPH{zEBO{52alIOA;?4?CQ9ekgXS=iv6@Tk*{Sw-80rkxKH>I**kfEYo$8!Ewyh% zX(4*a?jgORCbp$<=DrM&Tho;<6^3>&$O7!eWyI4Y)jiA2!EkGRrZ_IeKkK?YxnVaA z2bfT^nlOVThv9OUarLOjZopP}6jkp$nd+9Yyr$J_wnu3P*(`p%lUF2<5G<^}_B^~9 zYv)~(!lqolHlo#=_VU!hGp1Kl6*}#SFPZpcg1+0szJGJO-WITK#FM&cPX5~ zLB^lcZ)+g9(jI{;=xM}yWqF65ZeTCq79P`e6HuG4zEXm@kC_l50Yv(}Gjcv-@~Y8L zn0jC#u6%W-dguwQS5qP zS;^P%^%snyL)Iim@Y}voF$rTecCTHwY~(PE&V(rxF})>2Qnp(To{MsA7DR0 z#|}j8_vXo}PxY$oEZCAfzNpsq;e(I)!K;H7Cr9Zbv31LeRb{;jcln7|L(!55QGwx; zg;JgY$$xoI@#8&($4i<1jr+}0t)!+YUQ5(P4=!JgH20gD59LZq^?uoSiM?mr?sNlH zHQ7t{F2nVs(DUX;u^Qszx+)@5b_w7s9u%=lhg8ddK6Q)===$S<(WkGhS!i2^*vAC# zrI-^ZO3V)9qU=2-V)1;NPOyj}m27&6g)2}g9sOL?av;j4aNPuTRg9h4=Mh(qh+Y^k zv(f`3wzZ*b=SKm{B@2#76l(ObVt+rwvR;cmo$4gtY>a3n9r&pSW_{;DNWrd~TNICc zb;DEzkpJOcvvH3y1+gS-9(Ob$CcabZ@^-MF;+xBRVD*mtj7U-TD?x;A>xlDz8f+}*f?6lyQsXnE?^+o`A)F;~eRHa|=V8`#xK zDmhQB&cxTaeBWSWs-bSr5ot$smF^`NQK|f#LmS6AtW5dg(kT$XD>YKlnH&MDYU^}p zCSA$Xek9Gm=3Z@K*x;eBHRF0z|B3Z9O5ljFt3A3cGH0c1+nbM=J*=cat*MRb){7 zLsVJ4lJq2ReG_MGFjhTS{~f`dNHSWXAF4)_R-W?rL+_CM3}9tD5$67gM|XKxOnZ6D zn1bD&!P%BwolNELL6=LFoLHivyMv0Ai!u5!9UNMfpRMVOMmLQ-X5TD+ks7zAIs(uo zz#I#s2>Pc`29Dpa%SY!xgG1#);{O@IM<58rE83E{cyGEOB;5HAZJjp@!{J+u{*&(0 zlf9zLbWlqzJ!jFE-L8=oV!p)JIxgbZ(0DE}MYB>NbrM=dzI6p^he#?AOA+jso&JjFV zVlX1A>C4%@{m~#Q)MH{}oBi**01Or2Q(aDzAflhdv2zhnP7Ub0R;dc$6U32sltayF zc!!+$L$n9^6yv3$#I!0z#$Uw0m*@)hew1sYdq0it=bEktC*-VGGy3XQFlhPk|Du|IfWLjflfbNMi~%A_Li(?1)bNQ@ujb-Wg>cHI-Xj={q$rigOCC3S`k$k}k&*;89@2|neym@=%|`tE z4`BJBoELkhNSw~{s?$qP;*k_d->uuX|FiT*#3*X~r#>rXhMd7TlQzT2%-Zr?6ajfIPEyad32 zofH7-oKTV2e&`K+0dGvyfOHFVN}8pPx8#8PV6cO2imvL5c@t+CaNB#@SWcRDE_VOU zC^m$yRgy(dg75*%b8keu%6qe+>UHH3)S6ePxM`zinSoZ!Wd%ZXq{%^&?)?~K7FN`V z>9VU?ys2MK+;=#>f;aAE>9ap>by5Sw?fdjJCtf|=)M(J&^V4L!`T(~JyxVX0-e0G_ zYIU5n;nyJ&b?f0>Bsx^B;?^Typm`t2b7=k(W<$uc(`TpZ5Ki7csPxHUi(Tz1D|R(2 z1#P0@D!mZ)o$-uC3UM;|YK25v!B^>R`y>y_v76B8#}N!k*+C3Om_4Kw zd1F)ya4pPwyiH+AB^Ys&vz{$$akEQR#&4y4q}R=w$peb>}NCT)w|s4G%V600z${s5=w809xx`Vr?hsI*xm zMmOTP6yrGi&cl6?;S0n*pl&``yM~cTS6XFDd1JQCaxMw)@2YH6=n?YW}jEj(MLPWY(~T6^<)xTO#}p<9V#~6ymjk*XSe?t3rm@Pf9nuxPi(G~YSiGRRc6^( zllE?i9Jpu+IOPzE{c#8|vp(iHn9;8oknF@7tjKt8W?;@q@vKwz?waz4YPe7T*?VXP z14&{A$R@}s&VAY|E(@0Z>^3)$FgrQwHf}*xv^wlHb8TTp?gCrSA*TT#W~1uZQOVEc zz=^xTAF7EW17fag<^V{@M}n=I_NxQZDU7G^l@q^K%|zc`U|XiInsn1|W;S$Q7E#K4 zG3~RXtf%a4AXacOhM##v{NY!j94`XlI-`2ZytK9^o=cCOP-t+ z3yGT|s%5Z-eqNRQdhobbZFv7peYuZ3D`ucE^&lwuy8EPSEN&lR&urbeIhTF~tXcP^ zuib~bPI@?IW#<`=ZKO<66nuyU@*2>6)o1rG1(7i_T%|hH(lxAg+0JhnOOr{z#qeag zSSt~FjP53oa%`657K-y}_P#T0c$7(zeIWv9zRwR3un)I7ba+ooS`)&p@)k+9)r<{}1Zqqe$}Ora3Fp?hQS=5n1#U*k(ruS+ZuNdo%=-kO`RYqG{Ltj>eJ)-Af> z3Jqe%!AY`KPpja@8;O%F(!njb^!dN=74mrUZw*h-JhdxdB!XEsKbwVjI+LY+ulaIZ zz1>FZ%h1J!5nV|QKqp>XExYW<0}w31Hntq*esZ+D%xzRJV!t)>?c~r60ggSGkC0}~ zO`R6YJWkAMIHl)iJ9g7MmN@9|app~U2;XWcFza<@RXpk9!`L(_~R(B^g`51Rj&oPEH(=JNT2`{hY3b&A77h@ z-;`LU_{QjdVZGigLQ*IuY3-!x0@(t$VXeR&Wh^~6FPs$@Ua9E24S3MX;|Dj4VZb@E z4riqCPz<%?QQyRor%!1&QbaWi%9iA!o}8f86ALZ-+~xfGQI}YbotGuB3>+K{TA<|%lc{Sr z6JH<^3v`i7q9z40t}SKyu+?uwj7pvnYsZnya+lL#{&VH3tGkIu&{Hh5+?UxvwUsQb zdR126mHU6S_ulVpzwiHWOI15)=*dc^FeSh!o`+mJX_djqS_wn_^^Kd+mxN@D>ILG6BoF`*BF3cO9zK*nw z<6FTBEt(%>C89Pbv1~u#NhnS}p=GbSUf$3_*})@NpRfS0j5^Z{xx+?0Uo3D?Z_^Nw_`$RA-W*OC5PBE#;$Wht7k@wOKg1 z*VjnXF%b(zjy~aL6C0OV%?TJOWzv>-bW?X_j|M-w7N+;%0CckCImN#WcOu;~ z_Hw8_>}^5{co>{JDNRIwIuB$W?++@ykF3>79u5Vk9WrdTu(n@Lak#IzBX-L`T374Y z^Y`+bDg7cJRLZiaN{CWE6?yq~M7@BV>juSvzJvR_IhVhq?XQ;VW~YODX-ksAET~21 z3q>OCf&AIWI+m0`yqk0$E)8c{7QP=-WD!fm%8zXO+zip37kF{8wic6xq;-g{$uqOl z>qVr;z(npZZ(#QRy*wTGx94=C?bkm$?{mPVj7@IIJpMYHia=IElBPpi1leaWjS#n&iYSp*Wtok&RKD`+E$CYbb zHJ_JNJQTdR(MjeedF74%IBu}^YD{B&l|!kfpafpcS!lIoU_^$NB*u~9pcycVRI*yQ zQCuJ`qiglzzM-;pgWa&~Ld5EBX5ooUJ5vr2J-AN#Bs*{U z`LMNGg$a4m0XpGr;YA?DZeSZK-w|0QY%5kx8hq4FR>)n|I8MUD$%Hb-z~Q8p6D81N zowsXj-1-!;S6?xd{cbto`KfvK5uooUR*n}V){-npmMM$#RvV#Yp-S%obBhV3mv$aP zo^^ngXZ0RrHItpE6AunTgn{gVzTc2)9Ix18`i)|xyZRBOYeYApqTsAuGp^Ab#0#iD#>$@lLpot0zHJAV z??#6+8mD1`NH2xYlB^M`_OM>3c**jP;y`V2*MYCshFQ&b6?uJ!wKcbbJ%(sadbU30 zUOyB2^)XIoLSvEd{NuR2Xvf2MjESt(2uO_G*I@&@H~!7_iWd_bh~71~1o{$;wi4_j zZNaWXihQo(xdIM(PY?-thlpazuO^^2#rwepH5vQR6!1zT=KOU#A7`kT&*qxX?nlXX zkX`3x`dvu-=5G7s6Xz9r;@V=n9Ok)S%z?x&Y#<&KO6Po@CW>@Z(C-T)1HgM9r8fAv zG(h@(Z8=i{_`M{BUh7jrd-zUd=EFyLGM#OY5^Nndo7(Ie@vx>%QxUZjKYYAS4rW%dAp|U*<#)~==CMz@V1oEk`tMa0lT%nqTOmVbV&dL4{--T8>aZ0ZNi> z8H&U@dtQ!XSY}-)`(5xz*HljuvJ>4+uazPjkzB(y%l>^z^ef%me22~o%OKV|g|GpB z!Q22J-YbvrC{l7WvX#IrX5BT%6ywEptN0T~BFNqujf0$(p26+v4HRE%oM|xGkkF(3x=r z-n=jWIwnnMG9D&@1KD^veg(Mz1Q)!s&gJt=4RBbQ+;F#T#SoxzmNuBV5E z90@z_Z*ks~-fXTOVbiScxAba6d6NAvk)0{!W$fkP2x}pdh~5xePaxX1S#gB^>BP6N z!*QBwO9my6mYJB5^L0Cxrj;y@IOBId)q7I7mPN)$Rzm!^K#vp?tp|J8Vf)@7+0^Ic zbA&E^TDdGS`zepTpvSB@jDRa`;-wDtMjaR%gf-fUO5MzWk1MpYzC-GHn4`(9NSCUZ zNWb8xq$&TdU`&HzyA7u=<%7uFm{o#71}qS3MP|2v5MxbVyThNzy$eE-=`FO{<0`r93Ba#P+U#I#r6m_P@ozT92|d=D2Eq?T0a+55Sqqs$J@ zRk!2Kb$q=c?wFjuuG6#CuTQegwQ6wnrf!&=+ZeO#NjX?W zdrUQy%aQ4PSpV+zzZ}eZL!EcKzE+H3djk@16~0jG@s2~Q{x5g-?~J6U(oQWaqwh&c zdhp`W4~|3n(}f2zDNZ{36hg702Rqv{uPF6{w=%e0=Fxg>QQ=XGHqgu?AxHFkA6fG>xdPQD5C#vn_}2d+qzn&>5%d?~Y zpeiHj?b09K3nWR4X_vlU`=-w5Sh~#-0JH{lZDI}q%@%XpoSRED_wXbf0Kef{PH+>! z+D%xc2(lTNzeIawS*s|%?v0WZ!-$HVa;}}ao^{?Y!)yIwzHS&;BdgeF`?_~;V^4?f zYA8qesmxqZ3)L)3qkI&*_RUCCibfjv$g6cZ{VaSp(j74+IA6}K#4z2mUC(rN>C(VJ zT=rDH;98dupC8boN9xxngX%p$CDG^b)SENE{WfPOyPTjGKa7T-$TMCR_Y1Tja~~O} zua(37l+|otb<(_1!j={^PVt%?wOmh}btG+ye88DIXd^=U^($-}`A2<;v_bO5}Ad9Pw%$D@BMzhYbKl~;VF!(Lvj>I6Z9?|E%Hlg$Eq_LK( zC){I{Pq#LTa<;a4Zq4UG{MANkeB0bgt1UbCeqXJF*yeK6(RwK9;Asy{A364uW%|jk?>y7Tm5Mp6G`Q=`{mCn!|6%>CH!T2HdTh>IWo^)YvCA8Ml2{+ zjXBE59Yeif>!oK6qZP-!0$`pe;Can7?&3wV4S4g;vi1r-)`U63po9=})I%jF@zZv? zl1jstto}nj${$WR2K}JnJJMvAN*COm74?R-1o3ckx~8s3vuf16Ob=YRKbNQL2e>&5bi zr#KSiQ7q09&L!^0OuqqO3v;z8+)=AID>=JOe%tnh23Y#0WqsCTLv-PM$^)9&bTOM; z*!%+Tow&R|^OlZH|Jj83&@I7ZORfxFoP}mSXkH%Rxf#$&FL5L{m%AKI#_s?S!P^}D z<1*IB1Yg}0I+nd}@S2D(IZZW)G<%;_9do9wHW{AbWaQ<^A*C2HGGp13S^v7eb4FFS zqQk=CEGM2^8>W5Nj6aE`Fr)ks`KlCH`aScB`K~BS=&e9((kZ2F9uFo9=UVq666;|9 znOfO_vTEu5rGdE1c78FF*X>uoZUHn6rWc~$_*1P`{ZuGJowX!6o0cRR4fP92xz>Dg zANtzjUM!!&tNWh0FQH%lVd_w>`?umASkfTaM+wZ}!$0p2pxp=i^&Yb4|2{6J!+8N!bAQ|_LU%q1Fk zj+~}OwLO-1q@_STN*b5TK3+Mj4sIJOFq#jpLkD~vRD{)>*AqmJ~*5!WTn-G zG`AWk({m^k3opvGY_|x*(=_`K~dU-Qv@gdS4X-2~ZB)Invw_FVK z8$FJuJr>2BhzbsM!?PFa$PFVBSuJ>OYPr%YQNS*_%K2dY`Hg2wZiop8IT+DWt^OQs z*s2V=CLrWG@=eO5A={^861|gd?Y)y8?YBOLaI!793y3a@&6*`J_5}{Slu8y{<;v2g+v2VDapSXZ1fGxB6j+_TaBSkEUfHV!F9A4tif*H@4s)L!cnhZzb=+ zQ6-nZu*r7QuNjy0uk1W*`Q@B9*{6MKLcdyOK}Zq$AgDYR45X3_L*Plvp&6mQZ!{6ERW8sba?#u%1QY`H%F33J})A-_zAhO zv;B`Bnr^w2j}daEv#pOi)8n2<-!qzd<#!;6tJR^>u#9kPzw5lAJujd7T13fq)yNXc z4EBD^no%=%Jm*E?zO_#DSkJZ2@bnfAd{M`1duAjlN$oE0ox~}3`k7Czcrp58|9!m_G%!;DAuMU%m}5~gKAnTv0Gp0$pzq%9WBx>{#9aglbNacf`hE~ z*LKo<7~3T@9n&%e<$CU2h^pgB*5^lW)*kkb$)_=@($YQVKy23ahl|m3HhipXk1uE) zaFUC;d%ybicPxt-chsinhGD*Z<9 z&Yg^{K<5a?k@FGxC8f7X3FWI5LMk^$+)@@tHY_R*-6*uNdOS7m_f4@qf%IQXjFaPx zC|1Z0>hk%ub7l$KXZ9mLx<)T|!%gHGyRGk4^{~=4nn%NQV4bS2npp087H0f)V#AMR z1+MMi$w2j#WY}#?_Px+`%zdR~b}#F#5zzASuXyd2VB?Y$%a$s-G&AfH^D73;XXufV z=iT{&pinsoITBJXlRT)pg6vpms3h-RSGoSPVwcPx>D~fPy!fN!k3M9;TjJ6#&GO@< zQEgSxa~<^6E~%+sy2g(I;#Z5r%4nUf{RBz|u9a&0t!n!V>0B)fm%1%?qqD{H0cOD9nI(WC88>vojs zX2iZ}g9S|C(P|pJS#XoB{&7FIjO9DtDZ&!XP4S$Yx!wCMIIGcBVm2@*l_xbsPO)9F2u(va^Y8OnT-wcyDkGj>4MFhS=<+Kv%7trS{*~hYNbcOwgj3 zJ;QP8?{B0U#&>PfL3w!^cN!%w%_$!Q14zgr00xl|9RE_`p@$>Nn|7m-CW9g2~Y zeOT<*H|u zHkb8KsAO{VO&XFLjhK1dV-~AHkHpu}0^O*;KQ+zFdacECNBhWNdJOC&ot1dEpK+Pb zdwru+$+RVCgKzRyS^C$rzYQi>I|wt5`t0%{Z(Fy1|MqHIQ21L;F!S`KTYW~)9w!>o zurJv!6`$I?^0#%)5_6N_|ETvm1eB0YI?-v1;RB-lvP8zGt&kg!loj8R7jV+qjXl$%R?&4?} zMNl6XN)tScXC7H1O8f_<2Bl(Bdt1Bd{OmRscSj$=(^o6ALP8eK0|lt+zc#b1^AzRm5XbZ1=lO=4d*5cb%8nc3(As4tJlAxBj_XXnU1o4m?ATloCC`_?$6t+Gd?xreMMkeuF|0r>u zMwuJy(v~6nqVy}GH2QhNhiInCSKMdtAI*6&u*g*wp$N``~oJfx4WwcsppbRfvTCuP$C9T6HU z?71MC;U!vKCvGtI$A(bauA*JZ#K-@BKvx2@l&h>+^UNjfb2Y5*dm%4idCd6WeVhEq z5*2`v#wjyIV({R}gAf7qA2F1SaG${n@%uaL{gyl$STOS|QR+ko%_+V@ZR8~y?>gnT zmHBT~UjZqrR(R$!-IHx!|9AfK4XD{m5)7X##T z>Ce(87=6((2=&8r9C!$DMjPF;($A&K8xKq>4cKJSWhGVT>i$$Gsj<1~%DcW$!|(lw zKB~wUyi_TDu90;Vzs z3r=tR;!DNOmk4unUs+QV2oR=sZb;W+2%sMmOA%#g2Yz=I^~pSN<+9l_ucr3CLKGea zP`TMJTuQ#)EQAo(u9hovqAklPnF2hKhW|PkF=BVxy-BDWG?R0p0Q-xloRPCy(}sgj z8gv*tH(TubfaQ513-9a_3MQ9LutVHOeJAh+8Hb1WT@Mr^U9GCSUU3uaQ{|+Ef-^zrL98WpnZ6d_ zh@8tOM%8RUz9*00kE`|>lq1Yo2y0h#yVl&%x#JX6Asu_yD{*&}JN7p~CU9d3y~&HV zb@E958gxn5=2vkQLVTjq&~e%EMGpIB8HCmyT{dh#Sq=`Yl?Ua&t4?3g+D^Y9(&Mdh zC!)n(BjQs)-PbM4hK}|*EVSzyh2xW|=hU6JYa@D8#&biL=!K9nc-eDsM~MImR4mWm zRQEL*aqakXvY8Qb`tF4|S*=BD=TRU8uqG9Wwha!Qqb;->5z=}#e4@w(*b2+h{B`g| zB_`A|cP;bFJF3(?7a*7ly1LOn92_$n3dB)GLAkd^_mq)9%pT)W;6NY=#qiS>q;X~^ zW++sMCD+&QQ-u1BI{CwIYUKP>L~78qRwQhctQv*LZ?wEU`jQRO

m!<`Pt56Y^tDC8pBtHsMTO?zTthgtB@7NLR5%BFFbfh=%!$(OULHpk0 zq+%L1xt>?mbac!+xg1`j9|xz2f4dR63|h`Jn-gjTjKQkifHIqu-iD_3kP3XM$XURxl2elim1m`I`E@Lwvi;6Qlq#Gucm4r|#^z?C9z5c|l zjt|q;TUGWw9j82=p8ozEa^nHg3e_p)uK82Vv>*(Yphq*32;|>1bOe&TO3YPc}$;ul>fa;zJV!S?WqG--EF7}G!b;6#Iw@gzgD!# zFpjTk+Tn+w?_*BuRp=g@l>f_aG+KU*6yyhuj8oywuY&|xZh77*L=dX{ySN?zlT`6^ zCq}t7B89h+_Jr4_-rSoBe!E{tK$9lTm z{N;?Z#H%{vS>Igg8E4h7rcwCV_<>A4sdT(3(|)5$2; zD|F;=nBH81zrcFFsUHFxFe&&w1davzF?GXtXGIF+8{w(Y;IrxAS+Gyt%)~Nah zak~-t2AAq?nUdD+SaASoD0Ni;hLgKEoaC{)t0e_7=_}}ko<$JdR4}9Gx3FS?S&v!t z!$UtK3nGxY!L8AL$Tpv=cT6^4txQR3@x&XqF4WCK0;WO?2lOGKeHp^`D?Ql=pX%?Z zYW~ss()T9NJIn{ahv3)WcOEltHimc}IJANJtJsWu_7Z*3X^BSMV z5AkMyo}gm7ajkViFc(y|3LdoGyd zxF2)l#KtUt`C7--MWoXhxfRCer<#_Wv&Q?)m9rOM!KP$ZBON0tICdYY4l-Nc;|Ixj zL6P@KaBK&|iMEuhKm^UI$PFF74 zeiy$-{_9DqLs)?grZw%gCPpjmwyd$n#Xv{nB5~%xlqrnr)5%s#vYESb*Wd=l#zuAe zb~3jh_xFmo0h8HDx8?0ou@?2$RhfR8v9f}oLpf`-HK;}9Cy-PVi%|;Ov~9q*z-5* ziNLoS5_f;ukcn8YtVQ!PJ{13*Yns+`C|w`(b3o{)l?7CMX-9#RpcZ$jfNCAjes2Rk z@*cS%9+i+vlm7i?nXsBF{8N44yqH&8JqH$-OW~e|8sec+)T${b96uBvn-wsUH?Mvz zYjv^cjf2+nFWNO$@-8i_8iv@G&xLN%g9hp!Zhabk<+IUPC`+xSSb0(}eaLx*_f+-5 z#Y@+J3Duwj?O9_wuDt9Msk-|0DJJo}t`xG>_gaUnes^!QoMoV;v!|Sz&vf%2qXgQ7 zsG@AB#H@djOP>}!t<)qUPLFIP9N}`;hg>S_epR|;ecp02`;;dahWpM5m@92`NBL*9 zs-r7*{#5LnmjVZ>ZHK(jGbm<#I`S&01FGS%u2X z*QrMxqn4-0Oz5Zz0RzK)LO8G4z)5U9M4BSZNjnr38Y*dg$)9Ng{n^5>PwxVS4`+HM(fPCSAaw0Z5PUnRjb6DBf|%U_N@;x8*)fxKQ$n!kvC7BMIbgU~eg{ z)TI2M^=noP{d=Rn;LSgi9vE;d8rZ%3{^0MpWU2o9=reu2QsBS5^87#Z`^V!Z&Gl4P z%k3-w{P5p7`7__;7d7|37WemR{Jnzz_e1g11*OnWR7wBO(EsZ{I_Jvo^&saU3Mau0c@WEE-v8L4ikcVMZa*|xyK z0HS!h(F5k8+Zffe(7YL1T|-P5z%>%&X%dd!{a3*MJ(ARwuMMd_$H4fL7mH63 zmW!7IZ3fr`9);Cn4mKu!i+fq1y{2FoP?Lj4?eZ`mOO*}Y`+U_?!g0r?W4ev8`@l6a zxs6y=jG3=yQ#aQQZ3mK^J>ZdZx>@xrridPwM5X(0Rh3iy&5gogs(k=AjSvh z;|Y2}3Fbb&tW%N%`*7^qQr-3+C{*MXB6NkryxEMN@QsI*3%O_2WF6g>Zy7Dk(<%ek zuqK?)0iCM9T$zr2>AtSHwIXDT6^ZyGjxO*P&VT9E^YKla%c%{*hiA~(=glCsgui+2 z@Ibys6K%3@j;8{ue*P?SKpSV?I<-GY*nc8dah zX`HFHYMw-tO1r?*6=VxjWR|~-L(FIhb`z`$H~xG7|6b_|p=8EXi5X~<2ih}|&)XHXx~n1kF(JADNNUN30oY;+Jp7M&ODcwBD(IJWlM&|GW=3u3G=$okh`izK&-^& zk9U#wmqgkE+db8Hf!;(T!uStydF_a%QDa5W=$G4&=PUkPx8e_OS^%2A!58NO^gE6} zwe9u5bAjq#S$QtC?|zaXU5{IPZ0i^T8i`lrXZ^k%50*47P)!)LJUQt)Cru~j)=iLh z79wiXE)IKze)!iBH8G7!EwHKX0dq`u>z@2E=9)PB!ywwGEfkfVXAJOldr#rm$Q@ia zzKunUVgh~4Z_NnYML2Eha1CM3X6~Q|N_7%GYH}$AWVUUUTgv;&jS13v%YxgmlZEAY z5ry+b(eQ^-_{BgRL%OSX4@5P<-OcQ7^=sc=F#AkjWA>?EXDIZ>$3D6 z*QD3607OIITVcrh#X#Gn&a607!WtMxI6pj}s|Ae*NJK*8^>e`9=K&ejfoPH!OaUFw zC*s=^?CRVj%fIRfZ`?K}OuIOrXwecsiU6rWjK5FTBgoxxFLuu6Ti%2Q@Nm?CS{%< zmfwd>)U%F6{`3C>E0x7$PV?ji|ydM9fie)dmd(amS0gcnQ`{f|} zAQ!@_shZo2VHVf}#|(zLg8FiNdKILX@0Hg&r4-dq51}h|`@I>xwh_*lF|IEU=ct!7 ztm(Fx%yZX>cV=gNDlg!EHN~D_-IVHK^$I)0cs-?}_Y`haW6~N_@ZmaN6p*W|GFr*D z2X!ApUjNK}94%K_u;=8ExR1%x03h~G_NF~r?s0g5v9hc!0-}O`x_csL3!f6ltawd> z&}VC{KjqB&cU`snz*{Dnet0!fd%|I5Uz!7Gs!c{@Gq;ibXpE{7MDXKKfi{nOIi47H z#WkJl;e&8z`TN0%8|Xt7HZf8zMJRLQkb?8~dJ2DGG|Is$No z7{k@I(c#PJHr#X%H`4rM%)`HH2;%MA90N}iq%4vHG+d+lx1sW;=!*8I`e1IAu^lhM zu@(bpEUMr);Pk=dK!lOgwhXFWl}^_GmS2 zK9JANYU}hot%Df=o?Ue!m3rYYwo&bZ^fzCon+~6eiQR>lF&_^($68_)Y)nlaed@3y z;@LDHSi@tx^Uj=7h_)!)t3CYuK^9nHOSc;i7n-D-pSj5Kc<>1ny?TcZXS$#DX3rWP zkrFl<4NSZD)YgvdMzT#6II*3J?hSmpcV)UdtR2Ykl@&f4Ofu&p5UX8?wWk%5h5z(# zE>NH>?>deZOSU%$QbulM-Sgfks}C;_8-vwwy%ZiQ4EGlPoit&w^IZb|Cocyk$#X=H zT?120f3#$5-SVi0-CIlYE?yrWgU$T@{Ht6hsHsR~hzKr%tkHf8lnqQX%k;raqnvEj zFk{SLu_53fpRFkgg>TdePvnK}I6?w%7DReFmNRd2r8!(}92fAC>VvJi2)a+2X}7)~ ze1xw1MGjkaiC9U>&qflARlJM!$VM;FpeZ*#maso$JJk!Q&G zQ;MM2%TQ&snPt!S%9G>Nx$sfa`sa&hvdm?bJ+C2q=<|^2#G^g2Ia6CDnSY;?33e)@ z?o<~FgCX!vH(7*73!|*nev!38E5vf|F}4$UK2>_3S)QG{rH9KE>Cp_Q6S;<>Cf5dg zt)iy=gEW-vt4HSAXWiAY?=WH_*56y}8YA0-ie-kZ7SWaltwY@@l}>iOe;PWv^D3z< zlnTf59i!kdYe1RLTzg1m5OF7Xm2i2*B3(_6#-!+S=3!(_V*z%mNDa+iw^?}*VeayF zO|Z9TKzP`m1QRD=IX{+jQccC<5?$4F{fmVd#HyYjmD|oh^S4Mc+f$0@YE%VWjvHraAw zd!A!Feqcl4$z#P?=V4wio<>V;-)&6O>i}i1ul;l}0W^Jo3^I5!-#Fl}wKSN#WEAb+Xd&n~ zZR8BmldR#@w zmEJv*PmHVqfWjFdmI!71XbCmb&41&wn7&mTwTIm^JN`{_`Iz;5@g#xqI5q$kdUb8& z2WB6`>AfrL(voo&T!!p`EN=)xrDg>Fz4?JG&uIFnE#rK7s7FH?L$hRi`-EeEfYR&sL2lC>u=%Q>Ybfr{3+h3>NnM6{q)cl zGlufAwM45(&DNz<^7H3Qy2SdFm<~Z6t);L)7PNwA(jTSlIpSh~$xu=^bYCwm_e{zz+|zC;{S6D< z{9T2aKvkTT4VaQ<_Dg2L!Qhqjf=W-T0r67n>N@wXi0u+Wie_(-=$mMGoBbCor99Pe zjIee{Lqna;T$ZTy$t@YDT86>VRZfPeYQ}NhhT~q-8wD(f6$Ytq^=P(C&d!KMFO#Cy zTI2iT)&hW4eF;y(nhpXQE7gcJ({@l7pkd8H@}YPK@>B+_Gw#~qEqFcQkJDt2q?97 zTiFMU8+Mdf2&cJE-tp}Wz(t4go~U{wt(*Mif=P3wZA=lQ_Ixn8Xkp4~x1m2i=pf3( zlD`~4ECJt{k5ShR48qxpwv|5>Jw&rS2ZZFbdFGz%fS^P(E2@#zN!jUKs}jB3(gH}5 zF1GYBvQ*vJ7qUJ&R>bulRuTWl-g3!W4B|rb=dr#mOH;WJIrW{9JJN+P+sHdF4zoXa zxAF38BrsPbY&-D-GaD>Uo`pYu9G-~CiLY8v8BGyLHp9ZKy7NDJLLs;etMPqUBi+`` zvGb#!o#Z~9d2@&+(+iv+5F}(tSHV*e>uT#&oOes>2N=E31a@gfSUM^GvMq4b%WE4+ z4EImBhx8TVwz5rFyay@&XyCG|}UKn2Nq3lLx@afUQdB=I5Undzk!(H?qmdlU`U!Mxj-mMip?Q@H4@s+#sryF>LPqm9)ia`QZPc^(YBw{{CNU2^$Xmev+IW^DxsAC1>WdPju= z%bG`Ff{9qPpTspRE>1zV3mE_@-`^L7mlZ9cgS=5Zlo7;(9hraWtLvBEQ!QH+_@N!u zuO5Ei_#(hX#PzbxvBM+*Ek@{dy32w40l@h3>K}Uj3*hL@zn)r@t(A1+lA!BYszh+He2UmhX{hH|#X9TlPA z75a0%{2*K#Xxf?r{-OCD+2?j7AU*V-B4Rt7Kq%Nigiwne*MJ8U&G*ujfv-S|D;L@n zdN`*&qor*GJ`qGa#*wy}{+`jfc}Hd{=;%zf1qf<8Pj?HpLgFTwF|2d^!VDfwUz)6XJZ6Fyuctmk&`H`g1f1s~_M7MYI$?uQHoaX+I0RLwP i{?}pp|ML+#zo-@F&{RlNYq>!F(Nxn@g(yFd{=Wc90pkn+ literal 0 HcmV?d00001 diff --git a/images/att_00005.png b/images/att_00005.png new file mode 100644 index 0000000000000000000000000000000000000000..de857c985b555f4c933babe4ca98eec0f65af6e7 GIT binary patch literal 8156 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 00000000..c09d5612 --- /dev/null +++ b/index.html @@ -0,0 +1,712 @@ + + + + + + + + + + +Welcome to fastcore – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Welcome to fastcore

+
+ +
+
+ Python goodies to make your coding faster, easier, and more maintainable +
+
+ + +
+ + + + +
+ + + +
+ + + +

Python is a powerful, dynamic language. Rather than bake everything into the language, it lets the programmer customize it to make it work for them. fastcore uses this flexibility to add to Python features inspired by other languages we’ve loved, like multiple dispatch from Julia, mixins from Ruby, and currying, binding, and more from Haskell. It also adds some “missing features” and clean up some rough edges in the Python standard library, such as simplifying parallel processing, and bringing ideas from NumPy over to Python’s list type.

+
+

Getting started

+

To install fastcore run: conda install fastcore -c fastai (if you use Anaconda, which we recommend) or pip install fastcore. For an editable install, clone this repo and run: pip install -e ".[dev]". fastcore is tested to work on Ubuntu, macOS and Windows (versions tested are those shown with the -latest suffix here).

+

fastcore contains many features, including:

+
    +
  • fastcore.test: Simple testing functions
  • +
  • fastcore.foundation: Mixins, delegation, composition, and more
  • +
  • fastcore.xtras: Utility functions to help with functional-style programming, parallel processing, and more
  • +
  • fastcore.dispatch: Multiple dispatch methods
  • +
  • fastcore.transform: Pipelines of composed partially reversible transformations
  • +
+

To get started, we recommend you read through the fastcore tour.

+
+
+

Contributing

+

After you clone this repository, please run nbdev_install_hooks in your terminal. This sets up git hooks, which clean up the notebooks to remove the extraneous stuff stored in the notebooks (e.g. which cells you ran) which causes unnecessary merge conflicts.

+

To run the tests in parallel, launch nbdev_test.

+

Before submitting a PR, check that the local library and notebooks match.

+
    +
  • If you made a change to the notebooks in one of the exported cells, you can export it to the library with nbdev_prepare.
  • +
  • If you made a change to the library, you can export it back to the notebooks with nbdev_update.
  • +
+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/meta.html b/meta.html new file mode 100644 index 00000000..4c054ef2 --- /dev/null +++ b/meta.html @@ -0,0 +1,1292 @@ + + + + + + + + + + +Meta – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Meta

+
+ +
+
+ Metaclasses +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from fastcore.foundation import *
+from nbdev.showdoc import *
+from fastcore.nb_imports import *
+
+

See this blog post for more information about metaclasses.

+
    +
  • FixSigMeta preserves information that enables intropsection of signatures (i.e. tab completion in IDEs) when certain types of inheritence would otherwise obfuscate this introspection.
  • +
  • PrePostInitMeta ensures that the classes defined with it run __pre_init__ and __post_init__ (without having to write self.__pre_init__() and self.__post_init__() in the actual init
  • +
  • NewChkMeta gives the PrePostInitMeta functionality and ensures classes defined with it don’t re-create an object of their type whenever it’s passed to the constructor
  • +
  • BypassNewMeta ensures classes defined with it can easily be casted form objects they subclass.
  • +
+
+

source

+
+

test_sig

+
+
 test_sig (f, b)
+
+

Test the signature of an object

+
+
def func_1(h,i,j): pass
+def func_2(h,i=3, j=[5,6]): pass
+
+class T:
+    def __init__(self, a, b): pass
+
+test_sig(func_1, '(h, i, j)')
+test_sig(func_2, '(h, i=3, j=[5, 6])')
+test_sig(T, '(a, b)')
+
+
+

source

+
+
+

FixSigMeta

+
+
 FixSigMeta (name, bases, dict)
+
+

A metaclass that fixes the signature on classes that override __new__

+

When you inherit from a class that defines __new__, or a metaclass that defines __call__, the signature of your __init__ method is obfuscated such that tab completion no longer works. FixSigMeta fixes this issue and restores signatures.

+

To understand what FixSigMeta does, it is useful to inspect an object’s signature. You can inspect the signature of an object with inspect.signature:

+
+
class T:
+    def __init__(self, a, b, c): pass
+    
+inspect.signature(T)
+
+
<Signature (a, b, c)>
+
+
+

This corresponds to tab completion working in the normal way:

+

Tab completion in a Jupyter Notebook.

+

However, when you inherhit from a class that defines __new__ or a metaclass that defines __call__ this obfuscates the signature by overriding your class with the signature of __new__, which prevents tab completion from displaying useful information:

+
+
class Foo:
+    def __new__(self, **args): pass
+
+class Bar(Foo):
+    def __init__(self, d, e, f): pass
+    
+inspect.signature(Bar)
+
+
<Signature (d, e, f)>
+
+
+

Tab completion in a Jupyter Notebook.

+

Finally, the signature and tab completion can be restored by inheriting from the metaclass FixSigMeta as shown below:

+
+
class Bar(Foo, metaclass=FixSigMeta):
+    def __init__(self, d, e, f): pass
+    
+test_sig(Bar, '(d, e, f)')
+inspect.signature(Bar)
+
+
<Signature (d, e, f)>
+
+
+

Tab completion in a Jupyter Notebook.

+

If you need to define a metaclass that overrides __call__ (as done in PrePostInitMeta), you need to inherit from FixSigMeta instead of type when constructing the metaclass to preserve the signature in __init__. Be careful not to override __new__ when doing this:

+
+
class TestMeta(FixSigMeta):
+    # __new__ comes from FixSigMeta
+    def __call__(cls, *args, **kwargs): pass
+    
+class T(metaclass=TestMeta):
+    def __init__(self, a, b): pass
+    
+test_sig(T, '(a, b)')
+
+

On the other hand, if you fail to inherit from FixSigMeta when inheriting from a metaclass that overrides __call__, your signature will reflect that of __call__ instead (which is often undesirable):

+
+
class GenericMeta(type):
+    "A boilerplate metaclass that doesn't do anything for testing."
+    def __new__(cls, name, bases, dict):
+        return super().__new__(cls, name, bases, dict)
+    def __call__(cls, *args, **kwargs): pass
+
+class T2(metaclass=GenericMeta):
+    def __init__(self, a, b): pass
+
+# We can avoid this by inheriting from the metaclass `FixSigMeta`
+test_sig(T2, '(*args, **kwargs)')
+
+
+

source

+
+
+

PrePostInitMeta

+
+
 PrePostInitMeta (name, bases, dict)
+
+

A metaclass that calls optional __pre_init__ and __post_init__ methods

+

__pre_init__ and __post_init__ are useful for initializing variables or performing tasks prior to or after __init__ being called, respectively. Fore example:

+
+
class _T(metaclass=PrePostInitMeta):
+    def __pre_init__(self):  self.a  = 0; 
+    def __init__(self,b=0):  self.b = self.a + 1; assert self.b==1
+    def __post_init__(self): self.c = self.b + 2; assert self.c==3
+
+t = _T()
+test_eq(t.a, 0) # set with __pre_init__
+test_eq(t.b, 1) # set with __init__
+test_eq(t.c, 3) # set with __post_init__
+
+

One use for PrePostInitMeta is avoiding the __super__().__init__() boilerplate associated with subclassing, such as used in AutoInit.

+
+

source

+
+
+

AutoInit

+
+
 AutoInit (*args, **kwargs)
+
+

Same as object, but no need for subclasses to call super().__init__

+

This is normally used as a mixin, eg:

+
+
class TestParent():
+    def __init__(self): self.h = 10
+        
+class TestChild(AutoInit, TestParent):
+    def __init__(self): self.k = self.h + 2
+    
+t = TestChild()
+test_eq(t.h, 10) # h=10 is initialized in the parent class
+test_eq(t.k, 12)
+
+
+

source

+
+
+

NewChkMeta

+
+
 NewChkMeta (name, bases, dict)
+
+

Metaclass to avoid recreating object passed to constructor

+

NewChkMeta is used when an object of the same type is the first argument to your class’s constructor (i.e. the __init__ function), and you would rather it not create a new object but point to the same exact object.

+

This is used in L, for example, to avoid creating a new object when the object is already of type L. This allows the users to defenisvely instantiate an L object and just return a reference to the same object if it already happens to be of type L.

+

For example, the below class _T optionally accepts an object o as its first argument. A new object is returned upon instantiation per usual:

+
+
class _T():
+    "Testing"
+    def __init__(self, o): 
+        # if `o` is not an object without an attribute `foo`, set foo = 1
+        self.foo = getattr(o,'foo',1)
+
+
+
t = _T(3)
+test_eq(t.foo,1) # 1 was not of type _T, so foo = 1
+
+t2 = _T(t) #t1 is of type _T
+assert t is not t2 # t1 and t2 are different objects
+
+

However, if we want _T to return a reference to the same object when passed an an object of type _T we can inherit from the NewChkMeta class as illustrated below:

+
+
class _T(metaclass=NewChkMeta):
+    "Testing with metaclass NewChkMeta"
+    def __init__(self, o=None, b=1):
+        # if `o` is not an object without an attribute `foo`, set foo = 1
+        self.foo = getattr(o,'foo',1)
+        self.b = b
+
+

We can now test t and t2 are now pointing at the same object when using this new definition of _T:

+
+
t = _T(3)
+test_eq(t.foo,1) # 1 was not of type _T, so foo = 1
+
+t2 = _T(t) # t2 will now reference t
+
+test_is(t, t2) # t and t2 are the same object
+t2.foo = 5 # this will also change t.foo to 5 because it is the same object
+test_eq(t.foo, 5)
+test_eq(t2.foo, 5)
+
+

However, there is one exception to how NewChkMeta works. If you pass any additional arguments in the constructor a new object is returned, even if the first object is of the same type. For example, consider the below example where we pass the additional argument b into the constructor:

+
+
t3 = _T(t, b=1)
+assert t3 is not t
+
+t4 = _T(t) # without any arguments the constructor will return a reference to the same object
+assert t4 is t
+
+

Finally, it should be noted that NewChkMeta as well as all other metaclases in this section, inherit from FixSigMeta. This means class signatures will always be preserved when inheriting from this metaclass (see docs for FixSigMeta for more details):

+
+
test_sig(_T, '(o=None, b=1)')
+
+
+

source

+
+
+

BypassNewMeta

+
+
 BypassNewMeta (name, bases, dict)
+
+

Metaclass: casts x to this class if it’s of type cls._bypass_type

+

BypassNewMeta is identical to NewChkMeta, except for checking for a class as the same type, we instead check for a class of type specified in attribute _bypass_type.

+

In NewChkMeta, objects of the same type passed to the constructor (without arguments) would result into a new variable referencing the same object. However, with BypassNewMeta this only occurs if the type matches the _bypass_type of the class you are defining:

+
+
class _TestA: pass
+class _TestB: pass
+
+class _T(_TestA, metaclass=BypassNewMeta):
+    _bypass_type=_TestB
+    def __init__(self,x): self.x=x
+
+

In the below example, t does not refer to t2 because t is of type _TestA while _T._bypass_type is of type TestB:

+
+
t = _TestA()
+t2 = _T(t)
+assert t is not t2
+
+

However, if t is set to _TestB to match _T._bypass_type, then both t and t2 will refer to the same object.

+
+
t = _TestB()
+t2 = _T(t)
+t2.new_attr = 15
+
+test_is(t, t2)
+# since t2 just references t these will be the same
+test_eq(t.new_attr, t2.new_attr)
+
+# likewise, chaning an attribute on t will also affect t2 because they both point to the same object.
+t.new_attr = 9
+test_eq(t2.new_attr, 9)
+
+
+
+

Metaprogramming

+
+

source

+
+

empty2none

+
+
 empty2none (p)
+
+

Replace Parameter.empty with None

+
+

source

+
+
+

anno_dict

+
+
 anno_dict (f)
+
+

__annotation__ dictionary withemptycast toNone`, returning empty if doesn’t exist

+
+
def _f(a:int, b:L)->str: ...
+test_eq(anno_dict(_f), {'a': int, 'b': L, 'return': str})
+
+
+

source

+
+
+

use_kwargs_dict

+
+
 use_kwargs_dict (keep=False, **kwargs)
+
+

Decorator: replace **kwargs in signature with names params

+

Replace all **kwargs with named arguments like so:

+
+
@use_kwargs_dict(y=1,z=None)
+def foo(a, b=1, **kwargs): pass
+
+test_sig(foo, '(a, b=1, *, y=1, z=None)')
+
+

Add named arguments, but optionally keep **kwargs by setting keep=True:

+
+
@use_kwargs_dict(y=1,z=None, keep=True)
+def foo(a, b=1, **kwargs): pass
+
+test_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')
+
+
+

source

+
+
+

use_kwargs

+
+
 use_kwargs (names, keep=False)
+
+

Decorator: replace **kwargs in signature with names params

+

use_kwargs is different than use_kwargs_dict as it only replaces **kwargs with named parameters without any default values:

+
+
@use_kwargs(['y', 'z'])
+def foo(a, b=1, **kwargs): pass
+
+test_sig(foo, '(a, b=1, *, y=None, z=None)')
+
+

You may optionally keep the **kwargs argument in your signature by setting keep=True:

+
+
@use_kwargs(['y', 'z'], keep=True)
+def foo(a, *args, b=1, **kwargs): pass
+test_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')
+
+
+

source

+
+
+

delegates

+
+
 delegates (to:function=None, keep=False, but:list=None)
+
+

Decorator: replace **kwargs in signature with params from to

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
tofunctionNoneDelegatee
keepboolFalseKeep kwargs in decorated function?
butlistNoneExclude these parameters from signature
+

A common Python idiom is to accept **kwargs in addition to named parameters that are passed onto other function calls. It is especially common to use **kwargs when you want to give the user an option to override default parameters of any functions or methods being called by the parent function.

+

For example, suppose we have have a function foo that passes arguments to baz like so:

+
+
def baz(a, b:int=2, c:int=3): return a + b + c
+
+def foo(c, a, **kwargs):
+    return c + baz(a, **kwargs)
+
+assert foo(c=1, a=1) == 7
+
+

The problem with this approach is the api for foo is obfuscated. Users cannot introspect what the valid arguments for **kwargs are without reading the source code. When a user tries tries to introspect the signature of foo, they are presented with this:

+
+
inspect.signature(foo)
+
+
<Signature (c, a, **kwargs)>
+
+
+

We can address this issue by using the decorator delegates to include parameters from other functions. For example, if we apply the delegates decorator to foo to include parameters from baz:

+
+
@delegates(baz)
+def foo(c, a, **kwargs):
+    return c + baz(a, **kwargs)
+
+test_sig(foo, '(c, a, *, b: int = 2)')
+inspect.signature(foo)
+
+
<Signature (c, a, *, b: int = 2)>
+
+
+

We can optionally decide to keep **kwargs by setting keep=True:

+
+
@delegates(baz, keep=True)
+def foo(c, a, **kwargs):
+    return c + baz(a, **kwargs)
+
+inspect.signature(foo)
+
+
<Signature (c, a, *, b: int = 2, **kwargs)>
+
+
+

It is important to note that only parameters with default parameters are included. For example, in the below scenario only c, but NOT e and d are included in the signature of foo after applying delegates:

+
+
def basefoo(e, d, c=2): pass
+
+@delegates(basefoo)
+def foo(a, b=1, **kwargs): pass
+inspect.signature(foo) # e and d are not included b/c they don't have default parameters.
+
+
<Signature (a, b=1, *, c=2)>
+
+
+

The reason that required arguments (i.e. those without default parameters) are automatically excluded is that you should be explicitly implementing required arguments into your function’s signature rather than relying on delegates.

+

Additionally, you can exclude specific parameters from being included in the signature with the but parameter. In the example below, we exclude the parameter d:

+
+
def basefoo(e, c=2, d=3): pass
+
+@delegates(basefoo, but= ['d'])
+def foo(a, b=1, **kwargs): pass
+
+test_sig(foo, '(a, b=1, *, c=2)')
+inspect.signature(foo)
+
+
<Signature (a, b=1, *, c=2)>
+
+
+

You can also use delegates between methods in a class. Here is an example of delegates with class methods:

+
+
# example 1: class methods
+class _T():
+    @classmethod
+    def foo(cls, a=1, b=2):
+        pass
+    
+    @classmethod
+    @delegates(foo)
+    def bar(cls, c=3, **kwargs):
+        pass
+
+test_sig(_T.bar, '(c=3, *, a=1, b=2)')
+
+

Here is the same example with instance methods:

+
+
# example 2: instance methods
+class _T():
+    def foo(self, a=1, b=2):
+        pass
+    
+    @delegates(foo)
+    def bar(self, c=3, **kwargs):
+        pass
+
+t = _T()
+test_sig(t.bar, '(c=3, *, a=1, b=2)')
+
+

You can also delegate between classes. By default, the delegates decorator will delegate to the superclass:

+
+
class BaseFoo:
+    def __init__(self, e, c=2): pass
+
+@delegates()# since no argument was passsed here we delegate to the superclass
+class Foo(BaseFoo):
+    def __init__(self, a, b=1, **kwargs): super().__init__(**kwargs)
+
+test_sig(Foo, '(a, b=1, *, c=2)')
+
+
+

source

+
+
+

method

+
+
 method (f)
+
+

Mark f as a method

+

The method function is used to change a function’s type to a method. In the below example we change the type of a from a function to a method:

+
+
def a(x=2): return x + 1
+assert type(a).__name__ == 'function'
+
+a = method(a)
+assert type(a).__name__ == 'method'
+
+
+

source

+
+
+

funcs_kwargs

+
+
 funcs_kwargs (as_method=False)
+
+

Replace methods in cls._methods with those from kwargs

+

The func_kwargs decorator allows you to add a list of functions or methods to an existing class. You must set this list as a class attribute named _methods when defining your class. Additionally, you must incldue the **kwargs argument in the ___init__ method of your class.

+

After defining your class this way, you can add functions to your class upon instantation as illusrated below.

+

For example, we define class T to allow adding the function b to class T as follows (note that this function is stored as an attribute of T and doesn’t have access to cls or self):

+
+
@funcs_kwargs
+class T:
+    _methods=['b'] # allows you to add method b upon instantiation
+    def __init__(self, f=1, **kwargs): pass # don't forget to include **kwargs in __init__
+    def a(self): return 1
+    def b(self): return 2
+    
+t = T()
+test_eq(t.a(), 1)
+test_eq(t.b(), 2)
+
+

Because we defined the class T this way, the signature of T indicates the option to add the function or method(s) specified in _methods. In this example, b is added to the signature:

+
+
test_sig(T, '(f=1, *, b=None)')
+inspect.signature(T)
+
+
<Signature (f=1, *, b=None)>
+
+
+

You can now add the function b to class T upon instantiation:

+
+
def _new_func(): return 5
+
+t = T(b = _new_func)
+test_eq(t.b(), 5)
+
+

If you try to add a function with a name not listed in _methods it will be ignored. In the below example, the attempt to add a function named a is ignored:

+
+
t = T(a = lambda:3)
+test_eq(t.a(), 1) # the attempt to add a is ignored and uses the original method instead.
+
+

Note that you can also add methods not defined in the original class as long it is specified in the _methods attribute:

+
+
@funcs_kwargs
+class T:
+    _methods=['c']
+    def __init__(self, f=1, **kwargs): pass
+
+t = T(c = lambda: 4)
+test_eq(t.c(), 4)
+
+

Until now, these examples showed how to add functions stored as an instance attribute without access to self. However, if you need access to self you can set as_method=True in the func_kwargs decorator to add a method instead:

+
+
def _f(self,a=1): return self.num + a # access the num attribute from the instance
+
+@funcs_kwargs(as_method=True)
+class T: 
+    _methods=['b']
+    num = 5
+    
+t = T(b = _f) # adds method b
+test_eq(t.b(5), 10) # self.num + 5 = 10
+
+

Here is an example of how you might use this functionality with inheritence:

+
+
def _f(self,a=1): return self.num * a #multiply instead of add 
+
+class T2(T):
+    def __init__(self,num):
+        super().__init__(b = _f) # add method b from the super class
+        self.num=num
+        
+t = T2(num=3)
+test_eq(t.b(a=5), 15) # 3 * 5 = 15
+test_sig(T2, '(num)')
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/net.html b/net.html new file mode 100644 index 00000000..45d8ca6f --- /dev/null +++ b/net.html @@ -0,0 +1,1042 @@ + + + + + + + + + + +Network functionality – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Network functionality

+
+ +
+
+ Network, HTTP, and URL functions +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from fastcore.test import *
+from nbdev.showdoc import *
+from fastcore.nb_imports import *
+
+
+

URLs

+
+

source

+
+

urlquote

+
+
 urlquote (url)
+
+

Update url’s path with urllib.parse.quote

+
+
urlquote("https://github.com/fastai/fastai/compare/master@{1.day.ago}…master")
+
+
'https://github.com/fastai/fastai/compare/master@%7B1.day.ago%7D%E2%80%A6master'
+
+
+
+
urlquote("https://www.google.com/search?q=你好")
+
+
'https://www.google.com/search?q=%E4%BD%A0%E5%A5%BD'
+
+
+
+

source

+
+
+

urlwrap

+
+
 urlwrap (url, data=None, headers=None)
+
+

Wrap url in a urllib Request with urlquote

+
+

source

+
+

HTTP4xxClientError

+
+
 HTTP4xxClientError (url, code, msg, hdrs, fp)
+
+

Base class for client exceptions (code 4xx) from url* functions

+
+

source

+
+
+

HTTP5xxServerError

+
+
 HTTP5xxServerError (url, code, msg, hdrs, fp)
+
+

Base class for server exceptions (code 5xx) from url* functions

+
+

source

+
+
+
+

urlopener

+
+
 urlopener ()
+
+
+

source

+
+
+

urlopen

+
+
 urlopen (url, data=None, headers=None, timeout=None, **kwargs)
+
+

Like urllib.request.urlopen, but first urlwrap the url, and encode data

+

With urlopen, the body of the response will also be returned in addition to the message if there is an error:

+
+
try: urlopen('https://api.github.com/v3')
+except HTTPError as e: 
+    print(e.code, e.msg)
+    assert 'documentation_url' in e.msg
+
+
404 Not Found
+====Error Body====
+{
+  "message": "Not Found",
+  "documentation_url": "https://docs.github.com/rest"
+}
+
+
+
+
+

source

+
+
+

urlread

+
+
 urlread (url, data=None, headers=None, decode=True, return_json=False,
+          return_headers=False, timeout=None, **kwargs)
+
+

Retrieve url, using data dict or kwargs to POST if present

+
+

source

+
+
+

urljson

+
+
 urljson (url, data=None, timeout=None)
+
+

Retrieve url and decode json

+
+
test_eq(urljson('https://httpbin.org/get')['headers']['User-Agent'], url_default_headers['User-Agent'])
+
+
+

source

+
+
+

urlcheck

+
+
 urlcheck (url, headers=None, timeout=10)
+
+
+

source

+
+
+

urlclean

+
+
 urlclean (url)
+
+

Remove fragment, params, and querystring from url if present

+
+
test_eq(urlclean('http://a.com/b?c=1#d'), 'http://a.com/b')
+
+
+

source

+
+
+

urlretrieve

+
+
 urlretrieve (url, filename=None, reporthook=None, data=None,
+              headers=None, timeout=None)
+
+

Same as urllib.request.urlretrieve but also works with Request objects

+
+

source

+
+
+

urldest

+
+
 urldest (url, dest=None)
+
+
+

source

+
+
+

urlsave

+
+
 urlsave (url, dest=None, reporthook=None, headers=None, timeout=None)
+
+

Retrieve url and save based on its name

+
+
#skip
+with tempfile.TemporaryDirectory() as d: urlsave('http://www.google.com/index.html', d)
+
+
+

source

+
+
+

urlvalid

+
+
 urlvalid (x)
+
+

Test if x is a valid URL

+
+
assert urlvalid('http://www.google.com/')
+assert not urlvalid('www.google.com/')
+assert not urlvalid(1)
+
+
+

source

+
+
+

urlrequest

+
+
 urlrequest (url, verb, headers=None, route=None, query=None, data=None,
+             json_data=True)
+
+

Request for url with optional route params replaced by route, plus query string, and post data

+
+
hdr = {'Hdr1':'1', 'Hdr2':'2'}
+req = urlrequest('http://example.com/{foo}/1', 'POST',
+                 headers=hdr, route={'foo':'3'}, query={'q':'4'}, data={'d':'5'})
+
+test_eq(req.headers, hdr)
+test_eq(req.full_url, 'http://example.com/3/1?q=4')
+test_eq(req.method, 'POST')
+test_eq(req.data, b'{"d": "5"}')
+
+
+
req = urlrequest('http://example.com/{foo}/1', 'POST', data={'d':'5','e':'6'}, headers=hdr, json_data=False)
+test_eq(req.data, b'd=5&e=6')
+
+
+

source

+
+
+

Request.summary

+
+
 Request.summary (skip=None)
+
+

Summary containing full_url, headers, method, and data, removing skip from headers

+
+
req.summary(skip='Hdr1')
+
+
{'full_url': 'http://example.com/{foo}/1',
+ 'method': 'POST',
+ 'data': b'd=5&e=6',
+ 'headers': {'Hdr2': '2'}}
+
+
+
+

source

+
+
+

urlsend

+
+
 urlsend (url, verb, headers=None, route=None, query=None, data=None,
+          json_data=True, return_json=True, return_headers=False,
+          debug=None, timeout=None)
+
+

Send request with urlrequest, converting result to json if return_json

+
+

source

+
+
+

do_request

+
+
 do_request (url, post=False, headers=None, **data)
+
+

Call GET or json-encoded POST on url, depending on post

+
+
+
+

Basic client/server

+
+

source

+
+

start_server

+
+
 start_server (port, host=None, dgram=False, reuse_addr=True,
+               n_queue=None)
+
+

Create a socket server on port, with optional host, of type dgram

+

You can create a TCP client and server pass an int as port and optional host. host defaults to your main network interface if not provided. You can create a Unix socket client and server by passing a string to port. A SOCK_STREAM socket is created by default, unless you pass dgram=True, in which case a SOCK_DGRAM socket is created. n_queue sets the listening queue size.

+
+

source

+
+
+

start_client

+
+
 start_client (port, host=None, dgram=False)
+
+

Create a socket client on port, with optional host, of type dgram

+
+

source

+
+
+

tobytes

+
+
 tobytes (s:str)
+
+

Convert s into HTTP-ready bytes format

+
+
test_eq(tobytes('foo\nbar'), b'foo\r\nbar')
+
+
+

source

+
+
+

http_response

+
+
 http_response (body=None, status=200, hdrs=None, **kwargs)
+
+

Create an HTTP-ready response, adding kwargs to hdrs

+
+
exp = b'HTTP/1.1 200 OK\r\nUser-Agent: me\r\nContent-Length: 4\r\n\r\nbody'
+test_eq(http_response('body', 200, User_Agent='me'), exp)
+
+
+

source

+
+
+

recv_once

+
+
 recv_once (host:str='localhost', port:int=8000)
+
+

Spawn a thread to receive a single HTTP request and store in d['r']

+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/parallel.html b/parallel.html new file mode 100644 index 00000000..c4a55dd6 --- /dev/null +++ b/parallel.html @@ -0,0 +1,976 @@ + + + + + + + + + + +Parallel – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Parallel

+
+ +
+
+ Threading and multiprocessing functions +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from fastcore.test import *
+from nbdev.showdoc import *
+from fastcore.nb_imports import *
+
+
+

source

+
+

threaded

+
+
 threaded (process=False)
+
+

Run f in a Thread (or Process if process=True), and returns it

+
+
@threaded
+def _1():
+    time.sleep(0.05)
+    print("second")
+    return 5
+
+@threaded
+def _2():
+    time.sleep(0.01)
+    print("first")
+
+a = _1()
+_2()
+time.sleep(0.1)
+
+
first
+second
+
+
+

After the thread is complete, the return value is stored in the result attr.

+
+
a.result
+
+
5
+
+
+
+

source

+
+
+

startthread

+
+
 startthread (f)
+
+

Like threaded, but start thread immediately

+
+
@startthread
+def _():
+    time.sleep(0.05)
+    print("second")
+
+@startthread
+def _():
+    time.sleep(0.01)
+    print("first")
+
+time.sleep(0.1)
+
+
first
+second
+
+
+
+

source

+
+
+

startproc

+
+
 startproc (f)
+
+

Like threaded(True), but start Process immediately

+
+
@startproc
+def _():
+    time.sleep(0.05)
+    print("second")
+
+@startproc
+def _():
+    time.sleep(0.01)
+    print("first")
+
+time.sleep(0.1)
+
+
first
+second
+
+
+
+

source

+
+
+

parallelable

+
+
 parallelable (param_name, num_workers, f=None)
+
+
+

source

+
+

ThreadPoolExecutor

+
+
 ThreadPoolExecutor (max_workers=4, on_exc=<built-in function print>,
+                     pause=0, **kwargs)
+
+

Same as Python’s ThreadPoolExecutor, except can pass max_workers==0 for serial execution

+
+

source

+
+
+

ProcessPoolExecutor

+
+
 ProcessPoolExecutor (max_workers=4, on_exc=<built-in function print>,
+                      pause=0, mp_context=None, initializer=None,
+                      initargs=())
+
+

Same as Python’s ProcessPoolExecutor, except can pass max_workers==0 for serial execution

+
+

source

+
+
+
+

parallel

+
+
 parallel (f, items, *args, n_workers=4, total=None, progress=None,
+           pause=0, method=None, threadpool=False, timeout=None,
+           chunksize=1, **kwargs)
+
+

Applies func in parallel to items, using n_workers

+
+

source

+
+
+

add_one

+
+
 add_one (x, a=1)
+
+
+
inp,exp = range(50),range(1,51)
+
+test_eq(parallel(add_one, inp, n_workers=2, progress=False), exp)
+test_eq(parallel(add_one, inp, threadpool=True, n_workers=2, progress=False), exp)
+test_eq(parallel(add_one, inp, n_workers=1, a=2), range(2,52))
+test_eq(parallel(add_one, inp, n_workers=0), exp)
+test_eq(parallel(add_one, inp, n_workers=0, a=2), range(2,52))
+
+

Use the pause parameter to ensure a pause of pause seconds between processes starting. This is in case there are race conditions in starting some process, or to stagger the time each process starts, for example when making many requests to a webserver. Set threadpool=True to use ThreadPoolExecutor instead of ProcessPoolExecutor.

+
+
from datetime import datetime
+
+
+
def print_time(i): 
+    time.sleep(random.random()/1000)
+    print(i, datetime.now())
+
+parallel(print_time, range(5), n_workers=2, pause=0.25);
+
+
0 2022-08-07 05:10:05.999916
+1 2022-08-07 05:10:06.252031
+2 2022-08-07 05:10:06.503603
+3 2022-08-07 05:10:06.755216
+4 2022-08-07 05:10:07.006702
+
+
+
+

source

+
+
+

run_procs

+
+
 run_procs (f, f_done, args)
+
+

Call f for each item in args in parallel, yielding f_done

+
+

source

+
+
+

parallel_gen

+
+
 parallel_gen (cls, items, n_workers=4, **kwargs)
+
+

Instantiate cls in n_workers procs & call each on a subset of items in parallel.

+
+
# class _C:
+#     def __call__(self, o): return ((i+1) for i in o)
+
+# items = range(5)
+
+# res = L(parallel_gen(_C, items, n_workers=0))
+# idxs,dat1 = zip(*res.sorted(itemgetter(0)))
+# test_eq(dat1, range(1,6))
+
+# res = L(parallel_gen(_C, items, n_workers=3))
+# idxs,dat2 = zip(*res.sorted(itemgetter(0)))
+# test_eq(dat2, dat1)
+
+

cls is any class with __call__. It will be passed args and kwargs when initialized. Note that n_workers instances of cls are created, one in each process. items are then split in n_workers batches and one is sent to each cls. The function then returns a generator of tuples of item indices and results.

+
+
class TestSleepyBatchFunc:
+    "For testing parallel processes that run at different speeds"
+    def __init__(self): self.a=1
+    def __call__(self, batch):
+        for k in batch:
+            time.sleep(random.random()/4)
+            yield k+self.a
+
+x = np.linspace(0,0.99,20)
+
+res = L(parallel_gen(TestSleepyBatchFunc, x, n_workers=2))
+test_eq(res.sorted().itemgot(1), x+1)
+
+ + +
+
+ +
+
+
+
# #|hide
+# from subprocess import Popen, PIPE
+# # test num_workers > 0 in scripts works when python process start method is spawn
+# process = Popen(["python", "parallel_test.py"], stdout=PIPE)
+# _, err = process.communicate(timeout=10)
+# exit_code = process.wait()
+# test_eq(exit_code, 0)
+
+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/py2pyi.html b/py2pyi.html new file mode 100644 index 00000000..52e110f6 --- /dev/null +++ b/py2pyi.html @@ -0,0 +1,1123 @@ + + + + + + + + + +Create delegated pyi – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Create delegated pyi

+
+ + + +
+ + + + +
+ + + +
+ + + +
+

Setup

+
+
+

Basics

+
+

source

+
+

imp_mod

+
+
 imp_mod (module_path, package=None)
+
+

Import dynamically the module referenced in fn

+
+
fn = Path('test_py2pyi.py')
+
+
+
mod = imp_mod(fn)
+a = mod.A()
+a.h()
+
+
1
+
+
+
+
tree = _get_tree(mod)
+
+
+
+
+

AST.__repr__

+
+
 AST.__repr__ ()
+
+
+
# for o in enumerate(tree.body): print(o)
+
+
+
node = tree.body[4]
+node
+
+
def f(a: int, b: str='a') -> str:
+    """I am f"""
+    return 1
+
+
+
+
isinstance(node, functypes)
+
+
True
+
+
+
+

source

+
+
+

has_deco

+
+
 has_deco (node:Union[ast.FunctionDef,ast.AsyncFunctionDef], name:str)
+
+

Check if a function node node has a decorator named name

+
+
nm = 'delegates'
+has_deco(node, nm)
+
+
False
+
+
+
+
node = tree.body[5]
+node
+
+
@delegates(f)
+def g(c, d: X, **kwargs) -> str:
+    """I am g"""
+    return 2
+
+
+
+
has_deco(node, nm)
+
+
True
+
+
+
+
+
+

Function processing

+
+
def _proc_body   (node, mod): print('_proc_body', type(node))
+def _proc_func   (node, mod): print('_proc_func', type(node))
+def _proc_class  (node, mod): print('_proc_class', type(node))
+def _proc_patched(node, mod): print('_proc_patched', type(node))
+
+
+
_proc_mod(mod);
+
+
_proc_class <class 'ast.ClassDef'>
+_proc_body <class 'ast.FunctionDef'>
+_proc_func <class 'ast.FunctionDef'>
+_proc_body <class 'ast.FunctionDef'>
+_proc_class <class 'ast.ClassDef'>
+_proc_class <class 'ast.ClassDef'>
+_proc_patched <class 'ast.FunctionDef'>
+_proc_patched <class 'ast.FunctionDef'>
+_proc_body <class 'ast.FunctionDef'>
+
+
+
+
node.name
+
+
'g'
+
+
+
+
sym = getattr(mod, node.name)
+sym
+
+
<function test_py2pyi.g(c, d: test_py2pyi.X, *, b: str = 'a') -> str>
+
+
+
+
sig = signature(sym)
+print(sig)
+
+
(c, d: test_py2pyi.X, *, b: str = 'a') -> str
+
+
+
+

source

+
+

sig2str

+
+
 sig2str (sig)
+
+
+

source

+
+
+

ast_args

+
+
 ast_args (func)
+
+
+
newargs = ast_args(sym)
+newargs
+
+
c, d: test_py2pyi.X, *, b: str='a'
+
+
+
+
node.args
+
+
c, d: X, **kwargs
+
+
+
+
node.args = newargs
+node
+
+
@delegates(f)
+def g(c, d: test_py2pyi.X, *, b: str='a') -> str:
+    """I am g"""
+    return 2
+
+
+
+
_body_ellip(node)
+node
+
+
@delegates(f)
+def g(c, d: test_py2pyi.X, *, b: str='a') -> str:
+    """I am g"""
+    ...
+
+
+
+
tree = _get_tree(mod)
+node = tree.body[5]
+node
+
+
@delegates(f)
+def g(c, d: X, **kwargs) -> str:
+    """I am g"""
+    return 2
+
+
+
+
_update_func(node, sym)
+node
+
+
def g(c, d: test_py2pyi.X, *, b: str='a') -> str:
+    """I am g"""
+    ...
+
+
+
+
tree = _proc_mod(mod)
+tree.body[5]
+
+
_proc_class <class 'ast.ClassDef'>
+_proc_class <class 'ast.ClassDef'>
+_proc_class <class 'ast.ClassDef'>
+_proc_patched <class 'ast.FunctionDef'>
+_proc_patched <class 'ast.FunctionDef'>
+
+
+
def g(c, d: test_py2pyi.X, *, b: str='a') -> str:
+    """I am g"""
+    ...
+
+
+
+
+
+

Patch

+
+
node = tree.body[9]
+node
+
+
@patch
+@delegates(j)
+def k(self: (A, B), b: bool=False, **kwargs):
+    return 1
+
+
+
+
ann = node.args.args[0].annotation
+
+
+
if hasattr(ann, 'elts'): ann = ann.elts[0]
+
+
+
nm = ann.id
+nm
+
+
'A'
+
+
+
+
cls = getattr(mod, nm)
+sym = getattr(cls, node.name)
+
+
+
sig2str(signature(sym))
+
+
"(self: (test_py2pyi.A, test_py2pyi.B), b: bool = False, *, d: str = 'a')"
+
+
+
+
_update_func(node, sym)
+
+
+
node
+
+
@patch
+def k(self: (test_py2pyi.A, test_py2pyi.B), b: bool=False, *, d: str='a'):
+    ...
+
+
+
+
tree = _proc_mod(mod)
+tree.body[9]
+
+
_proc_class <class 'ast.ClassDef'>
+_proc_class <class 'ast.ClassDef'>
+_proc_class <class 'ast.ClassDef'>
+
+
+
@patch
+def k(self: (test_py2pyi.A, test_py2pyi.B), b: bool=False, *, d: str='a'):
+    ...
+
+
+
+
+

Class and file

+
+
tree = _get_tree(mod)
+node = tree.body[7]
+node
+
+
class A:
+
+    @delegates(j)
+    def h(self, b: bool=False, **kwargs):
+        a = 1
+        return a
+
+
+
+
node.body
+
+
[@delegates(j)
+ def h(self, b: bool=False, **kwargs):
+     a = 1
+     return a]
+
+
+
+
tree = _proc_mod(mod)
+tree.body[7]
+
+
class A:
+
+    def h(self, b: bool=False, *, d: str='a'):
+        ...
+
+
+
+

source

+
+

create_pyi

+
+
 create_pyi (fn, package=None)
+
+

Convert fname.py to fname.pyi by removing function bodies and expanding delegates kwargs

+
+
create_pyi(fn)
+
+
+
# fn = Path('/Users/jhoward/git/fastcore/fastcore/docments.py')
+# create_pyi(fn, 'fastcore')
+
+
+
+
+

Script

+
+

source

+
+

py2pyi

+
+
 py2pyi (fname:str, package:str=None)
+
+

Convert fname.py to fname.pyi by removing function bodies and expanding delegates kwargs

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
fnamestrThe file name to convert
packagestrNoneThe parent package
+
+

source

+
+
+

replace_wildcards

+
+
 replace_wildcards (path:str)
+
+

Expand wildcard imports in the specified Python file.

+ + + + + + + + + + + + + + + +
TypeDetails
pathstrPath to the Python file to process
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/robots.txt b/robots.txt new file mode 100644 index 00000000..7b04fdf9 --- /dev/null +++ b/robots.txt @@ -0,0 +1 @@ +Sitemap: https://fastcore.fast.ai/sitemap.xml diff --git a/script.html b/script.html new file mode 100644 index 00000000..b53a7efc --- /dev/null +++ b/script.html @@ -0,0 +1,999 @@ + + + + + + + + + + +Script - CLI – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Script - CLI

+
+ +
+
+ A fast way to turn your python function into a script. +
+
+ + +
+ + + + +
+ + + +
+ + + +

Part of fast.ai’s toolkit for delightful developer experiences.

+
+

Overview

+

Sometimes, you want to create a quick script, either for yourself, or for others. But in Python, that involves a whole lot of boilerplate and ceremony, especially if you want to support command line arguments, provide help, and other niceties. You can use argparse for this purpose, which comes with Python, but it’s complex and verbose.

+

fastcore.script makes life easier. There are much fancier modules to help you write scripts (we recommend Python Fire, and Click is also popular), but fastcore.script is very fast and very simple. In fact, it’s <50 lines of code! Basically, it’s just a little wrapper around argparse that uses modern Python features and some thoughtful defaults to get rid of the boilerplate.

+

For full details, see the docs for core.

+
+
+

Example

+

Here’s a complete example (available in examples/test_fastcore.py):

+
from fastcore.script import *
+@call_parse
+def main(msg:str,     # The message
+         upper:bool): # Convert to uppercase?
+    "Print `msg`, optionally converting to uppercase"
+    print(msg.upper() if upper else msg)
+

If you copy that info a file and run it, you’ll see:

+
$ examples/test_fastcore.py --help
+usage: test_fastcore.py [-h] [--upper] msg
+
+Print `msg`, optionally converting to uppercase
+
+positional arguments:
+  msg          The message
+
+optional arguments:
+  -h, --help   show this help message and exit
+  --upper      Convert to uppercase? (default: False)
+

As you see, we didn’t need any if __name__ == "__main__", we didn’t have to parse arguments, we just wrote a function, added a decorator to it, and added some annotations to our function’s parameters. As a bonus, we can also use this function directly from a REPL such as Jupyter Notebook - it’s not just for command line scripts!

+

You should provide a default (after the =) for any optional parameters. If you don’t provide a default for a parameter, then it will be a positional parameter.

+
+
+

Param annotations

+

If you want to use the full power of argparse, you can do so by using Param annotations instead of type annotations and docments, like so:

+
from fastcore.script import *
+@call_parse
+def main(msg:Param("The message", str),
+         upper:Param("Convert to uppercase?", store_true)):
+    "Print `msg`, optionally converting to uppercase"
+    print(msg.upper() if upper else msg)
+

If you use this approach, then each parameter in your function should have an annotation Param(...) (as in the example above). You can pass the following when calling Param: help,type,opt,action,nargs,const,choices,required . Except for opt, all of these are just passed directly to argparse, so you have all the power of that module at your disposal. Generally you’ll want to pass at least help (since this is provided as the help string for that parameter) and type (to ensure that you get the type of data you expect). opt is a bool that defines whether a param is optional or required (positional) - but you’ll generally not need to set this manually, because fastcore.script will set it for you automatically based on default values.

+
+
+

setuptools scripts

+

There’s a really nice feature of pip/setuptools that lets you create commandline scripts directly from functions, makes them available in the PATH, and even makes your scripts cross-platform (e.g. in Windows it creates an exe). fastcore.script supports this feature too. The trick to making a function available as a script is to add a console_scripts section to your setup file, of the form: script_name=module:function_name. E.g. in this case we use: test_fastcore.script=fastcore.script.test_cli:main. With this, you can then just type test_fastcore.script at any time, from any directory, and your script will be called (once it’s installed using one of the methods below).

+

You don’t actually have to write a setup.py yourself. Instead, just use nbdev. Then modify settings.ini as appropriate for your module/script. To install your script directly, you can type pip install -e .. Your script, when installed this way (it’s called an editable install), will automatically be up to date even if you edit it - there’s no need to reinstall it after editing. With nbdev you can even make your module and script available for installation directly from pip and conda by running make release.

+
+
+

API details

+
+

source

+
+

store_true

+
+
 store_true ()
+
+

Placeholder to pass to Param for store_true action

+
+

source

+
+
+

store_false

+
+
 store_false ()
+
+

Placeholder to pass to Param for store_false action

+
+

source

+
+
+

bool_arg

+
+
 bool_arg (v)
+
+

Use as type for Param to get bool behavior

+
+

source

+
+
+

clean_type_str

+
+
 clean_type_str (x:str)
+
+
+
class Test: pass
+
+test_eq(clean_type_str(argparse.ArgumentParser), 'argparse.ArgumentParser')
+test_eq(clean_type_str(Test), 'Test')
+test_eq(clean_type_str(int), 'int')
+test_eq(clean_type_str(float), 'float')
+test_eq(clean_type_str(store_false), 'store_false')
+
+
+

source

+
+
+

Param

+
+
 Param (help='', type=None, opt=True, action=None, nargs=None, const=None,
+        choices=None, required=None, default=None)
+
+

A parameter in a function used in anno_parser or call_parse

+
+
test_eq(repr(Param("Help goes here")), '<Help goes here>')
+test_eq(repr(Param("Help", int)), 'int <Help>')
+test_eq(repr(Param(help=None, type=int)), 'int')
+test_eq(repr(Param(help=None, type=None)), '')
+
+

Each parameter in your function should have an annotation Param(...). You can pass the following when calling Param: help,type,opt,action,nargs,const,choices,required (i.e. it takes the same parameters as argparse.ArgumentParser.add_argument, plus opt). Except for opt, all of these are just passed directly to argparse, so you have all the power of that module at your disposal. Generally you’ll want to pass at least help (since this is provided as the help string for that parameter) and type (to ensure that you get the type of data you expect).

+

opt is a bool that defines whether a param is optional or required (positional) - but you’ll generally not need to set this manually, because fastcore.script will set it for you automatically based on default values. You should provide a default (after the =) for any optional parameters. If you don’t provide a default for a parameter, then it will be a positional parameter.

+

Param’s __repr__ also allows for more informative function annotation when looking up the function’s doc using shift+tab. You see the type annotation (if there is one) and the accompanying help documentation with it.

+
+
def f(required:Param("Required param", int),
+      a:Param("param 1", bool_arg),
+      b:Param("param 2", str)="test"):
+    "my docs"
+    ...
+
+
+
help(f)
+
+
Help on function f in module __main__:
+
+f(required: int <Required param>, a: bool_arg <param 1>, b: str <param 2> = 'test')
+    my docs
+
+
+
+
+
p = Param(help="help", type=int)
+p.set_default(1)
+test_eq(p.kwargs, {'help': 'help (default: 1)', 'type': int, 'default': 1})
+
+
+

source

+
+
+

anno_parser

+
+
 anno_parser (func, prog:str=None)
+
+

Look at params (annotated with Param) in func and return an ArgumentParser

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
funcFunction to get arguments from
progstrNoneThe name of the program
+

This converts a function with parameter annotations of type Param into an argparse.ArgumentParser object. Function arguments with a default provided are optional, and other arguments are positional.

+
+
_en = str_enum('_en', 'aa','bb','cc')
+def f(required:Param("Required param", int),
+      a:Param("param 1", bool_arg),
+      b:Param("param 2", str)="test",
+      c:Param("param 3", _en)=_en.aa):
+    "my docs"
+    ...
+
+p = anno_parser(f, 'progname')
+p.print_help()
+
+
usage: progname [-h] [--b B] [--c {aa,bb,cc}] required a
+
+my docs
+
+positional arguments:
+  required        Required param
+  a               param 1
+
+optional arguments:
+  -h, --help      show this help message and exit
+  --b B           param 2 (default: test)
+  --c {aa,bb,cc}  param 3 (default: aa)
+
+
+

It also works with type annotations and docments:

+
+
def g(required:int,  # Required param
+      a:bool_arg,    # param 1
+      b="test",      # param 2
+      c:_en=_en.aa): # param 3
+    "my docs"
+    ...
+
+p = anno_parser(g, 'progname')
+p.print_help()
+
+
usage: progname [-h] [--b B] [--c {aa,bb,cc}] required a
+
+my docs
+
+positional arguments:
+  required        Required param
+  a               param 1
+
+optional arguments:
+  -h, --help      show this help message and exit
+  --b B           param 2 (default: test)
+  --c {aa,bb,cc}  param 3 (default: aa)
+
+
+
+

source

+
+
+

args_from_prog

+
+
 args_from_prog (func, prog)
+
+

Extract args from prog

+

Sometimes it’s convenient to extract arguments from the actual name of the called program. args_from_prog will do this, assuming that names and values of the params are separated by a #. Optionally there can also be a prefix separated by ## (double underscore).

+
+
exp = {'a': False, 'b': 'baa'}
+test_eq(args_from_prog(f, 'foo##a#0#b#baa'), exp)
+test_eq(args_from_prog(f, 'a#0#b#baa'), exp)
+
+
+

source

+
+
+

call_parse

+
+
 call_parse (func=None, nested=False)
+
+

Decorator to create a simple CLI from func using anno_parser

+
+
@call_parse
+def test_add(
+    a:int=0,  # param a
+    b:int=0  # param 1
+):
+    "Add up `a` and `b`"
+    return a + b
+
+

call_parse decorated functions work as regular functions and also as command-line interface functions.

+
+
test_eq(test_add(1,2), 3)
+
+

This is the main way to use fastcore.script; decorate your function with call_parse, add Param annotations (as shown above) or type annotations and docments, and it can then be used as a script.

+

Use the nested keyword argument to create nested parsers, where earlier parsers consume only their known args from sys.argv before later parsers are used. This is useful to create one command line application that executes another. For example:

+
myrunner --keyword 1 script.py -- <script.py args>
+

A separating -- after the first application’s args is recommended though not always required, otherwise args may be parsed in unexpected ways. For example:

+
myrunner script.py -h
+

would display myrunner’s help and not script.py’s.

+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/search.json b/search.json new file mode 100644 index 00000000..3387eecc --- /dev/null +++ b/search.json @@ -0,0 +1,632 @@ +[ + { + "objectID": "xml.html", + "href": "xml.html", + "title": "XML", + "section": "", + "text": "from IPython.display import Markdown\nfrom pprint import pprint\n\n\nsource\n\nFT\n\n FT (tag:str, cs:tuple, attrs:dict=None, void_=False, **kwargs)\n\nA ‘Fast Tag’ structure, containing tag,children,and attrs\n\nsource\n\n\nattrmap\n\n attrmap (o)\n\n\nsource\n\n\nvalmap\n\n valmap (o)\n\n\nsource\n\n\nft\n\n ft (tag:str, *c, void_:bool=False, attrmap:<built-\n infunctioncallable>=<function attrmap>, valmap:<built-\n infunctioncallable>=<function valmap>, **kw)\n\nCreate an FT structure for to_xml()\n\na = Body(Div('hi', a=1, b=True, cls=()), P('hi', cls=['a',1], style=dict(a=1,b=2)))\na\n\nbody((div(('hi',),{'a': 1, 'b': True, 'class': None}), p(('hi',),{'class': 'a 1', 'style': 'a:1; b:2'})),{})\n\n\nThe main HTML tags are exported as ft partials.\nAttributes are passed as keywords. Use ‘klass’ and ‘fr’ instead of ‘class’ and ‘for’, to avoid Python reserved word clashes.\n\nsource\n\n\nHtml\n\n Html (*c, doctype=True, **kwargs)\n\nAn HTML tag, optionally preceeded by !DOCTYPE HTML\n\nsamp = Html(\n Head(Title('Some page')),\n Body(Div('Some text\\nanother line', (Input(name=\"jph's\"), Img(src=\"filename\", data=1)),\n cls=['myclass', 'another'],\n style={'padding':1, 'margin':2}))\n)\npprint(samp)\n\n(!doctype((),{'html': True}),\n html((head((title(('Some page',),{}),),{}), body((div(('Some text\\nanother line', input((),{'name': \"jph's\"}), img((),{'src': 'filename', 'data': 1})),{'class': 'myclass another', 'style': 'padding:1; margin:2'}),),{})),{}))\n\n\nThe three elements of the list can also be accessed with property names, so you don’t have to remember their order.\n\nelem = P('Some text', id=\"myid\")\nprint(elem.tag)\nprint(elem.children)\nprint(elem.attrs)\n\np\n('Some text',)\n{'id': 'myid'}\n\n\nYou can also get and set attrs directly:\n\nelem.id = 'newid'\nprint(elem.id, elem.get('id'), elem.get('foo', 'missing'))\nelem\n\nnewid newid missing\n\n\np(('Some text',),{'id': 'newid'})\n\n\n\nsource\n\n\nSafe\n*str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str\nCreate a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.*\n\nsource\n\n\nto_xml\n\n to_xml (elm, lvl=0, indent:bool=True)\n\nConvert ft element tree into an XML string\n\nh = to_xml(samp)\nprint(h)\n\n<!doctype html>\n\n<html>\n <head><title>Some page</title>\n</head>\n <body><div class=\"myclass another\" style=\"padding:1; margin:2\">\nSome text\nanother line\n <input name=\"jph's\">\n <img src=\"filename\" data=\"1\">\n</div>\n</body>\n</html>\n\n\n\n\nclass PageTitle:\n def __ft__(self): return H1(\"Hello\")\n\nclass HomePage:\n def __ft__(self): return Div(PageTitle(), Div('hello'))\n\nh = to_xml(Div(HomePage()))\nexpected_output = \"\"\"<div>\n <div>\n <h1>Hello</h1>\n <div>hello</div>\n </div>\n</div>\n\"\"\"\nassert h == expected_output\n\n\nh = to_xml(samp, indent=False)\nprint(h)\n\n<!doctype html><html><head><title>Some page</title>\n</head><body><div class=\"myclass another\" style=\"padding:1; margin:2\">\nSome text\nanother line\n <input name=\"jph's\">\n <img src=\"filename\" data=\"1\">\n</div>\n</body></html>\n\n\nInteroperability both directions with Django and Jinja using the html() protocol:\n\ndef _esc(s): return s.__html__() if hasattr(s, '__html__') else Safe(escape(s))\n\nr = Safe('<b>Hello from Django</b>')\nprint(to_xml(Div(r)))\nprint(_esc(Div(P('Hello from fastcore <3'))))\n\n<div><b>Hello from Django</b></div>\n\n<div><p>Hello from fastcore <3</p>\n</div>\n\n\n\n\nsource\n\n\nhighlight\n\n highlight (s, lang='html')\n\nMarkdown to syntax-highlight s in language lang\n\nsource\n\n\nshowtags\n\n showtags (s)\n\n\nsource\n\n\ngetattr\n\n __getattr__ (tag)\n\n\nsource\n\n\nFT.__call__\n\n FT.__call__ (*c, **kw)\n\nCall self as a function.\nYou can also reorder the children to come after the attrs, if you use this alternative syntax for FT where the children are in a second pair of () (behind the scenes this is because FT implements __call__ to add children).\n\nBody(klass='myclass')(\n Div(style='padding:3px')(\n 'Some text ',\n I(spurious=True)('in italics'),\n Input(name='me'),\n Img(src=\"filename\", data=1)\n )\n)\n\n<body class=\"myclass\"><div style=\"padding:3px\">\nSome text \n <i spurious>in italics</i>\n <input name=\"me\">\n <img src=\"filename\" data=\"1\">\n</div>\n</body>", + "crumbs": [ + "XML" + ] + }, + { + "objectID": "net.html", + "href": "net.html", + "title": "Network functionality", + "section": "", + "text": "from fastcore.test import *\nfrom nbdev.showdoc import *\nfrom fastcore.nb_imports import *", + "crumbs": [ + "Network functionality" + ] + }, + { + "objectID": "net.html#urls", + "href": "net.html#urls", + "title": "Network functionality", + "section": "URLs", + "text": "URLs\n\nsource\n\nurlquote\n\n urlquote (url)\n\nUpdate url’s path with urllib.parse.quote\n\nurlquote(\"https://github.com/fastai/fastai/compare/master@{1.day.ago}…master\")\n\n'https://github.com/fastai/fastai/compare/master@%7B1.day.ago%7D%E2%80%A6master'\n\n\n\nurlquote(\"https://www.google.com/search?q=你好\")\n\n'https://www.google.com/search?q=%E4%BD%A0%E5%A5%BD'\n\n\n\nsource\n\n\nurlwrap\n\n urlwrap (url, data=None, headers=None)\n\nWrap url in a urllib Request with urlquote\n\nsource\n\nHTTP4xxClientError\n\n HTTP4xxClientError (url, code, msg, hdrs, fp)\n\nBase class for client exceptions (code 4xx) from url* functions\n\nsource\n\n\nHTTP5xxServerError\n\n HTTP5xxServerError (url, code, msg, hdrs, fp)\n\nBase class for server exceptions (code 5xx) from url* functions\n\nsource\n\n\n\nurlopener\n\n urlopener ()\n\n\nsource\n\n\nurlopen\n\n urlopen (url, data=None, headers=None, timeout=None, **kwargs)\n\nLike urllib.request.urlopen, but first urlwrap the url, and encode data\nWith urlopen, the body of the response will also be returned in addition to the message if there is an error:\n\ntry: urlopen('https://api.github.com/v3')\nexcept HTTPError as e: \n print(e.code, e.msg)\n assert 'documentation_url' in e.msg\n\n404 Not Found\n====Error Body====\n{\n \"message\": \"Not Found\",\n \"documentation_url\": \"https://docs.github.com/rest\"\n}\n\n\n\n\nsource\n\n\nurlread\n\n urlread (url, data=None, headers=None, decode=True, return_json=False,\n return_headers=False, timeout=None, **kwargs)\n\nRetrieve url, using data dict or kwargs to POST if present\n\nsource\n\n\nurljson\n\n urljson (url, data=None, timeout=None)\n\nRetrieve url and decode json\n\ntest_eq(urljson('https://httpbin.org/get')['headers']['User-Agent'], url_default_headers['User-Agent'])\n\n\nsource\n\n\nurlcheck\n\n urlcheck (url, headers=None, timeout=10)\n\n\nsource\n\n\nurlclean\n\n urlclean (url)\n\nRemove fragment, params, and querystring from url if present\n\ntest_eq(urlclean('http://a.com/b?c=1#d'), 'http://a.com/b')\n\n\nsource\n\n\nurlretrieve\n\n urlretrieve (url, filename=None, reporthook=None, data=None,\n headers=None, timeout=None)\n\nSame as urllib.request.urlretrieve but also works with Request objects\n\nsource\n\n\nurldest\n\n urldest (url, dest=None)\n\n\nsource\n\n\nurlsave\n\n urlsave (url, dest=None, reporthook=None, headers=None, timeout=None)\n\nRetrieve url and save based on its name\n\n#skip\nwith tempfile.TemporaryDirectory() as d: urlsave('http://www.google.com/index.html', d)\n\n\nsource\n\n\nurlvalid\n\n urlvalid (x)\n\nTest if x is a valid URL\n\nassert urlvalid('http://www.google.com/')\nassert not urlvalid('www.google.com/')\nassert not urlvalid(1)\n\n\nsource\n\n\nurlrequest\n\n urlrequest (url, verb, headers=None, route=None, query=None, data=None,\n json_data=True)\n\nRequest for url with optional route params replaced by route, plus query string, and post data\n\nhdr = {'Hdr1':'1', 'Hdr2':'2'}\nreq = urlrequest('http://example.com/{foo}/1', 'POST',\n headers=hdr, route={'foo':'3'}, query={'q':'4'}, data={'d':'5'})\n\ntest_eq(req.headers, hdr)\ntest_eq(req.full_url, 'http://example.com/3/1?q=4')\ntest_eq(req.method, 'POST')\ntest_eq(req.data, b'{\"d\": \"5\"}')\n\n\nreq = urlrequest('http://example.com/{foo}/1', 'POST', data={'d':'5','e':'6'}, headers=hdr, json_data=False)\ntest_eq(req.data, b'd=5&e=6')\n\n\nsource\n\n\nRequest.summary\n\n Request.summary (skip=None)\n\nSummary containing full_url, headers, method, and data, removing skip from headers\n\nreq.summary(skip='Hdr1')\n\n{'full_url': 'http://example.com/{foo}/1',\n 'method': 'POST',\n 'data': b'd=5&e=6',\n 'headers': {'Hdr2': '2'}}\n\n\n\nsource\n\n\nurlsend\n\n urlsend (url, verb, headers=None, route=None, query=None, data=None,\n json_data=True, return_json=True, return_headers=False,\n debug=None, timeout=None)\n\nSend request with urlrequest, converting result to json if return_json\n\nsource\n\n\ndo_request\n\n do_request (url, post=False, headers=None, **data)\n\nCall GET or json-encoded POST on url, depending on post", + "crumbs": [ + "Network functionality" + ] + }, + { + "objectID": "net.html#basic-clientserver", + "href": "net.html#basic-clientserver", + "title": "Network functionality", + "section": "Basic client/server", + "text": "Basic client/server\n\nsource\n\nstart_server\n\n start_server (port, host=None, dgram=False, reuse_addr=True,\n n_queue=None)\n\nCreate a socket server on port, with optional host, of type dgram\nYou can create a TCP client and server pass an int as port and optional host. host defaults to your main network interface if not provided. You can create a Unix socket client and server by passing a string to port. A SOCK_STREAM socket is created by default, unless you pass dgram=True, in which case a SOCK_DGRAM socket is created. n_queue sets the listening queue size.\n\nsource\n\n\nstart_client\n\n start_client (port, host=None, dgram=False)\n\nCreate a socket client on port, with optional host, of type dgram\n\nsource\n\n\ntobytes\n\n tobytes (s:str)\n\nConvert s into HTTP-ready bytes format\n\ntest_eq(tobytes('foo\\nbar'), b'foo\\r\\nbar')\n\n\nsource\n\n\nhttp_response\n\n http_response (body=None, status=200, hdrs=None, **kwargs)\n\nCreate an HTTP-ready response, adding kwargs to hdrs\n\nexp = b'HTTP/1.1 200 OK\\r\\nUser-Agent: me\\r\\nContent-Length: 4\\r\\n\\r\\nbody'\ntest_eq(http_response('body', 200, User_Agent='me'), exp)\n\n\nsource\n\n\nrecv_once\n\n recv_once (host:str='localhost', port:int=8000)\n\nSpawn a thread to receive a single HTTP request and store in d['r']", + "crumbs": [ + "Network functionality" + ] + }, + { + "objectID": "test.html", + "href": "test.html", + "title": "Test", + "section": "", + "text": "We can check that code raises an exception when that’s expected (test_fail).\nTo test for equality or inequality (with different types of things) we define a simple function test that compares two objects with a given cmp operator.\n\nsource\n\n\n\n test_fail (f, msg='', contains='', args=None, kwargs=None)\n\nFails with msg unless f() raises an exception and (optionally) has contains in e.args\n\ndef _fail(): raise Exception(\"foobar\")\ntest_fail(_fail, contains=\"foo\")\n\ndef _fail(): raise Exception()\ntest_fail(_fail)\n\nWe can also pass args and kwargs to function to check if it fails with special inputs.\n\ndef _fail_args(a):\n if a == 5:\n raise ValueError\ntest_fail(_fail_args, args=(5,))\ntest_fail(_fail_args, kwargs=dict(a=5))\n\n\nsource\n\n\n\n\n test (a, b, cmp, cname=None)\n\nassert that cmp(a,b); display inputs and cname or cmp.__name__ if it fails\n\ntest([1,2],[1,2], operator.eq)\ntest_fail(lambda: test([1,2],[1], operator.eq))\ntest([1,2],[1], operator.ne)\ntest_fail(lambda: test([1,2],[1,2], operator.ne))\n\n\n\n\n\n\n all_equal (a, b)\n\nCompares whether a and b are the same length and have the same contents\n\ntest(['abc'], ['abc'], all_equal)\ntest_fail(lambda: test(['abc'],['cab'], all_equal))\n\n\n\n\n\n\n equals (a, b)\n\nCompares a and b for equality; supports sublists, tensors and arrays too\n\ntest([['abc'],['a']], [['abc'],['a']], equals)\ntest([['abc'],['a'],'b', [['x']]], [['abc'],['a'],'b', [['x']]], equals) # supports any depth and nested structure\n\n\nsource\n\n\n\n\n nequals (a, b)\n\nCompares a and b for not equals\n\ntest(['abc'], ['ab' ], nequals)", + "crumbs": [ + "Test" + ] + }, + { + "objectID": "test.html#simple-test-functions", + "href": "test.html#simple-test-functions", + "title": "Test", + "section": "", + "text": "We can check that code raises an exception when that’s expected (test_fail).\nTo test for equality or inequality (with different types of things) we define a simple function test that compares two objects with a given cmp operator.\n\nsource\n\n\n\n test_fail (f, msg='', contains='', args=None, kwargs=None)\n\nFails with msg unless f() raises an exception and (optionally) has contains in e.args\n\ndef _fail(): raise Exception(\"foobar\")\ntest_fail(_fail, contains=\"foo\")\n\ndef _fail(): raise Exception()\ntest_fail(_fail)\n\nWe can also pass args and kwargs to function to check if it fails with special inputs.\n\ndef _fail_args(a):\n if a == 5:\n raise ValueError\ntest_fail(_fail_args, args=(5,))\ntest_fail(_fail_args, kwargs=dict(a=5))\n\n\nsource\n\n\n\n\n test (a, b, cmp, cname=None)\n\nassert that cmp(a,b); display inputs and cname or cmp.__name__ if it fails\n\ntest([1,2],[1,2], operator.eq)\ntest_fail(lambda: test([1,2],[1], operator.eq))\ntest([1,2],[1], operator.ne)\ntest_fail(lambda: test([1,2],[1,2], operator.ne))\n\n\n\n\n\n\n all_equal (a, b)\n\nCompares whether a and b are the same length and have the same contents\n\ntest(['abc'], ['abc'], all_equal)\ntest_fail(lambda: test(['abc'],['cab'], all_equal))\n\n\n\n\n\n\n equals (a, b)\n\nCompares a and b for equality; supports sublists, tensors and arrays too\n\ntest([['abc'],['a']], [['abc'],['a']], equals)\ntest([['abc'],['a'],'b', [['x']]], [['abc'],['a'],'b', [['x']]], equals) # supports any depth and nested structure\n\n\nsource\n\n\n\n\n nequals (a, b)\n\nCompares a and b for not equals\n\ntest(['abc'], ['ab' ], nequals)", + "crumbs": [ + "Test" + ] + }, + { + "objectID": "test.html#test_eq-test_ne-etc", + "href": "test.html#test_eq-test_ne-etc", + "title": "Test", + "section": "test_eq test_ne, etc…", + "text": "test_eq test_ne, etc…\nJust use test_eq/test_ne to test for ==/!=. test_eq_type checks things are equal and of the same type. We define them using test:\n\nsource\n\ntest_eq\n\n test_eq (a, b)\n\ntest that a==b\n\ntest_eq([1,2],[1,2])\ntest_eq([1,2],map(int,[1,2]))\ntest_eq(array([1,2]),array([1,2]))\ntest_eq(array([1,2]),array([1,2]))\ntest_eq([array([1,2]),3],[array([1,2]),3])\ntest_eq(dict(a=1,b=2), dict(b=2,a=1))\ntest_fail(lambda: test_eq([1,2], 1), contains=\"==\")\ntest_fail(lambda: test_eq(None, np.array([1,2])), contains=\"==\")\ntest_eq({'a', 'b', 'c'}, {'c', 'a', 'b'})\n\n\ndf1 = pd.DataFrame(dict(a=[1,2],b=['a','b']))\ndf2 = pd.DataFrame(dict(a=[1,2],b=['a','b']))\ndf3 = pd.DataFrame(dict(a=[1,2],b=['a','c']))\n\ntest_eq(df1,df2)\ntest_eq(df1.a,df2.a)\ntest_fail(lambda: test_eq(df1,df3), contains='==')\nclass T(pd.Series): pass\ntest_eq(df1.iloc[0], T(df2.iloc[0])) # works with subclasses\n\n\ntest_eq(torch.zeros(10), torch.zeros(10, dtype=torch.float64))\ntest_eq(torch.zeros(10), torch.ones(10)-1)\ntest_fail(lambda:test_eq(torch.zeros(10), torch.ones(1, 10)), contains='==')\ntest_eq(torch.zeros(3), [0,0,0])\n\n\nsource\n\n\ntest_eq_type\n\n test_eq_type (a, b)\n\ntest that a==b and are same type\n\ntest_eq_type(1,1)\ntest_fail(lambda: test_eq_type(1,1.))\ntest_eq_type([1,1],[1,1])\ntest_fail(lambda: test_eq_type([1,1],(1,1)))\ntest_fail(lambda: test_eq_type([1,1],[1,1.]))\n\n\nsource\n\n\ntest_ne\n\n test_ne (a, b)\n\ntest that a!=b\n\ntest_ne([1,2],[1])\ntest_ne([1,2],[1,3])\ntest_ne(array([1,2]),array([1,1]))\ntest_ne(array([1,2]),array([1,1]))\ntest_ne([array([1,2]),3],[array([1,2])])\ntest_ne([3,4],array([3]))\ntest_ne([3,4],array([3,5]))\ntest_ne(dict(a=1,b=2), ['a', 'b'])\ntest_ne(['a', 'b'], dict(a=1,b=2))\n\n\nsource\n\n\nis_close\n\n is_close (a, b, eps=1e-05)\n\nIs a within eps of b\n\nsource\n\n\ntest_close\n\n test_close (a, b, eps=1e-05)\n\ntest that a is within eps of b\n\ntest_close(1,1.001,eps=1e-2)\ntest_fail(lambda: test_close(1,1.001))\ntest_close([-0.001,1.001], [0.,1.], eps=1e-2)\ntest_close(np.array([-0.001,1.001]), np.array([0.,1.]), eps=1e-2)\ntest_close(array([-0.001,1.001]), array([0.,1.]), eps=1e-2)\n\n\nsource\n\n\ntest_is\n\n test_is (a, b)\n\ntest that a is b\n\ntest_fail(lambda: test_is([1], [1]))\na = [1]\ntest_is(a, a)\nb = [2]; test_fail(lambda: test_is(a, b))\n\n\nsource\n\n\ntest_shuffled\n\n test_shuffled (a, b)\n\ntest that a and b are shuffled versions of the same sequence of items\n\na = list(range(50))\nb = copy(a)\nrandom.shuffle(b)\ntest_shuffled(a,b)\ntest_fail(lambda:test_shuffled(a,a))\n\n\na = 'abc'\nb = 'abcabc'\ntest_fail(lambda:test_shuffled(a,b))\n\n\na = ['a', 42, True] \nb = [42, True, 'a']\ntest_shuffled(a,b)\n\n\nsource\n\n\ntest_stdout\n\n test_stdout (f, exp, regex=False)\n\nTest that f prints exp to stdout, optionally checking as regex\n\ntest_stdout(lambda: print('hi'), 'hi')\ntest_fail(lambda: test_stdout(lambda: print('hi'), 'ho'))\ntest_stdout(lambda: 1+1, '')\ntest_stdout(lambda: print('hi there!'), r'^hi.*!$', regex=True)\n\n\nsource\n\n\ntest_warns\n\n test_warns (f, show=False)\n\n\ntest_warns(lambda: warnings.warn(\"Oh no!\"))\ntest_fail(lambda: test_warns(lambda: 2+2), contains='No warnings raised')\n\n\ntest_warns(lambda: warnings.warn(\"Oh no!\"), show=True)\n\n<class 'UserWarning'>: Oh no!\n\n\n\nim = Image.open(TEST_IMAGE).resize((128,128)); im\n\n\n\n\n\n\n\n\n\nim = Image.open(TEST_IMAGE_BW).resize((128,128)); im\n\n\n\n\n\n\n\n\n\nsource\n\n\ntest_fig_exists\n\n test_fig_exists (ax)\n\nTest there is a figure displayed in ax\n\nfig,ax = plt.subplots()\nax.imshow(array(im));\n\n\n\n\n\n\n\n\n\ntest_fig_exists(ax)\n\n\nsource\n\n\nExceptionExpected\n\n ExceptionExpected (ex=<class 'Exception'>, regex='')\n\nContext manager that tests if an exception is raised\n\ndef _tst_1(): assert False, \"This is a test\"\ndef _tst_2(): raise SyntaxError\n\nwith ExceptionExpected(): _tst_1()\nwith ExceptionExpected(ex=AssertionError, regex=\"This is a test\"): _tst_1()\nwith ExceptionExpected(ex=SyntaxError): _tst_2()\n\nexception is an abbreviation for ExceptionExpected().\n\nwith exception: _tst_1()", + "crumbs": [ + "Test" + ] + }, + { + "objectID": "xdg.html", + "href": "xdg.html", + "title": "XDG", + "section": "", + "text": "See the XDG Base Directory Specification for more information.", + "crumbs": [ + "XDG" + ] + }, + { + "objectID": "xdg.html#overview", + "href": "xdg.html#overview", + "title": "XDG", + "section": "Overview", + "text": "Overview\nxdg_cache_home, xdg_config_home, xdg_data_home, and xdg_state_home return pathlib.Path objects containing the value of the environment variable named XDG_CACHE_HOME, XDG_CONFIG_HOME, XDG_DATA_HOME, and XDG_STATE_HOME respectively, or the default defined in the specification if the environment variable is unset, empty, or contains a relative path rather than absolute path.\nxdg_config_dirs and xdg_data_dirs return a list of pathlib.Path objects containing the value, split on colons, of the environment variable named XDG_CONFIG_DIRS and XDG_DATA_DIRS respectively, or the default defined in the specification if the environment variable is unset or empty. Relative paths are ignored, as per the specification.\nxdg_runtime_dir returns a pathlib.Path object containing the value of the XDG_RUNTIME_DIR environment variable, or None if the environment variable is not set, or contains a relative path rather than absolute path.", + "crumbs": [ + "XDG" + ] + }, + { + "objectID": "xdg.html#helpers", + "href": "xdg.html#helpers", + "title": "XDG", + "section": "Helpers", + "text": "Helpers\nWe’ll start by defining a context manager that temporarily sets an environment variable to demonstrate the behaviour of each helper function:\n\nfrom contextlib import contextmanager\n\n\n@contextmanager\ndef env(variable, value):\n old = os.environ.get(variable, None)\n try:\n os.environ[variable] = value\n yield\n finally:\n if old is None: del os.environ[variable]\n else: os.environ[variable] = old\n\n\nsource\n\nxdg_cache_home\n\n xdg_cache_home ()\n\nPath corresponding to XDG_CACHE_HOME\n\nfrom fastcore.test import *\n\n\ntest_eq(xdg_cache_home(), Path.home()/'.cache')\nwith env('XDG_CACHE_HOME', '/home/fastai/.cache'):\n test_eq(xdg_cache_home(), Path('/home/fastai/.cache'))\n\n\nsource\n\n\nxdg_config_dirs\n\n xdg_config_dirs ()\n\nPaths corresponding to XDG_CONFIG_DIRS\n\ntest_eq(xdg_config_dirs(), [Path('/etc/xdg')])\nwith env('XDG_CONFIG_DIRS', '/home/fastai/.xdg:/home/fastai/.config'):\n test_eq(xdg_config_dirs(), [Path('/home/fastai/.xdg'), Path('/home/fastai/.config')])\n\n\nsource\n\n\nxdg_config_home\n\n xdg_config_home ()\n\nPath corresponding to XDG_CONFIG_HOME\n\ntest_eq(xdg_config_home(), Path.home()/'.config')\nwith env('XDG_CONFIG_HOME', '/home/fastai/.config'):\n test_eq(xdg_config_home(), Path('/home/fastai/.config'))\n\n\nsource\n\n\nxdg_data_dirs\n\n xdg_data_dirs ()\n\nPaths corresponding to XDG_DATA_DIRS`\n\nsource\n\n\nxdg_data_home\n\n xdg_data_home ()\n\nPath corresponding to XDG_DATA_HOME\n\ntest_eq(xdg_data_home(), Path.home()/'.local/share')\nwith env('XDG_DATA_HOME', '/home/fastai/.data'):\n test_eq(xdg_data_home(), Path('/home/fastai/.data'))\n\n\nsource\n\n\nxdg_runtime_dir\n\n xdg_runtime_dir ()\n\nPath corresponding to XDG_RUNTIME_DIR\n\nsource\n\n\nxdg_state_home\n\n xdg_state_home ()\n\nPath corresponding to XDG_STATE_HOME\n\ntest_eq(xdg_state_home(), Path.home()/'.local/state')\nwith env('XDG_STATE_HOME', '/home/fastai/.state'):\n test_eq(xdg_state_home(), Path('/home/fastai/.state'))\n\n\nCopyright © 2016-2021 Scott Stevenson scott@stevenson.io\nModifications copyright © 2022 onwards Jeremy Howard", + "crumbs": [ + "XDG" + ] + }, + { + "objectID": "meta.html", + "href": "meta.html", + "title": "Meta", + "section": "", + "text": "from fastcore.foundation import *\nfrom nbdev.showdoc import *\nfrom fastcore.nb_imports import *\nSee this blog post for more information about metaclasses.\nsource", + "crumbs": [ + "Meta" + ] + }, + { + "objectID": "meta.html#metaprogramming", + "href": "meta.html#metaprogramming", + "title": "Meta", + "section": "Metaprogramming", + "text": "Metaprogramming\n\nsource\n\nempty2none\n\n empty2none (p)\n\nReplace Parameter.empty with None\n\nsource\n\n\nanno_dict\n\n anno_dict (f)\n\n__annotation__ dictionary withemptycast toNone`, returning empty if doesn’t exist\n\ndef _f(a:int, b:L)->str: ...\ntest_eq(anno_dict(_f), {'a': int, 'b': L, 'return': str})\n\n\nsource\n\n\nuse_kwargs_dict\n\n use_kwargs_dict (keep=False, **kwargs)\n\nDecorator: replace **kwargs in signature with names params\nReplace all **kwargs with named arguments like so:\n\n@use_kwargs_dict(y=1,z=None)\ndef foo(a, b=1, **kwargs): pass\n\ntest_sig(foo, '(a, b=1, *, y=1, z=None)')\n\nAdd named arguments, but optionally keep **kwargs by setting keep=True:\n\n@use_kwargs_dict(y=1,z=None, keep=True)\ndef foo(a, b=1, **kwargs): pass\n\ntest_sig(foo, '(a, b=1, *, y=1, z=None, **kwargs)')\n\n\nsource\n\n\nuse_kwargs\n\n use_kwargs (names, keep=False)\n\nDecorator: replace **kwargs in signature with names params\nuse_kwargs is different than use_kwargs_dict as it only replaces **kwargs with named parameters without any default values:\n\n@use_kwargs(['y', 'z'])\ndef foo(a, b=1, **kwargs): pass\n\ntest_sig(foo, '(a, b=1, *, y=None, z=None)')\n\nYou may optionally keep the **kwargs argument in your signature by setting keep=True:\n\n@use_kwargs(['y', 'z'], keep=True)\ndef foo(a, *args, b=1, **kwargs): pass\ntest_sig(foo, '(a, *args, b=1, y=None, z=None, **kwargs)')\n\n\nsource\n\n\ndelegates\n\n delegates (to:function=None, keep=False, but:list=None)\n\nDecorator: replace **kwargs in signature with params from to\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\nto\nfunction\nNone\nDelegatee\n\n\nkeep\nbool\nFalse\nKeep kwargs in decorated function?\n\n\nbut\nlist\nNone\nExclude these parameters from signature\n\n\n\nA common Python idiom is to accept **kwargs in addition to named parameters that are passed onto other function calls. It is especially common to use **kwargs when you want to give the user an option to override default parameters of any functions or methods being called by the parent function.\nFor example, suppose we have have a function foo that passes arguments to baz like so:\n\ndef baz(a, b:int=2, c:int=3): return a + b + c\n\ndef foo(c, a, **kwargs):\n return c + baz(a, **kwargs)\n\nassert foo(c=1, a=1) == 7\n\nThe problem with this approach is the api for foo is obfuscated. Users cannot introspect what the valid arguments for **kwargs are without reading the source code. When a user tries tries to introspect the signature of foo, they are presented with this:\n\ninspect.signature(foo)\n\n<Signature (c, a, **kwargs)>\n\n\nWe can address this issue by using the decorator delegates to include parameters from other functions. For example, if we apply the delegates decorator to foo to include parameters from baz:\n\n@delegates(baz)\ndef foo(c, a, **kwargs):\n return c + baz(a, **kwargs)\n\ntest_sig(foo, '(c, a, *, b: int = 2)')\ninspect.signature(foo)\n\n<Signature (c, a, *, b: int = 2)>\n\n\nWe can optionally decide to keep **kwargs by setting keep=True:\n\n@delegates(baz, keep=True)\ndef foo(c, a, **kwargs):\n return c + baz(a, **kwargs)\n\ninspect.signature(foo)\n\n<Signature (c, a, *, b: int = 2, **kwargs)>\n\n\nIt is important to note that only parameters with default parameters are included. For example, in the below scenario only c, but NOT e and d are included in the signature of foo after applying delegates:\n\ndef basefoo(e, d, c=2): pass\n\n@delegates(basefoo)\ndef foo(a, b=1, **kwargs): pass\ninspect.signature(foo) # e and d are not included b/c they don't have default parameters.\n\n<Signature (a, b=1, *, c=2)>\n\n\nThe reason that required arguments (i.e. those without default parameters) are automatically excluded is that you should be explicitly implementing required arguments into your function’s signature rather than relying on delegates.\nAdditionally, you can exclude specific parameters from being included in the signature with the but parameter. In the example below, we exclude the parameter d:\n\ndef basefoo(e, c=2, d=3): pass\n\n@delegates(basefoo, but= ['d'])\ndef foo(a, b=1, **kwargs): pass\n\ntest_sig(foo, '(a, b=1, *, c=2)')\ninspect.signature(foo)\n\n<Signature (a, b=1, *, c=2)>\n\n\nYou can also use delegates between methods in a class. Here is an example of delegates with class methods:\n\n# example 1: class methods\nclass _T():\n @classmethod\n def foo(cls, a=1, b=2):\n pass\n \n @classmethod\n @delegates(foo)\n def bar(cls, c=3, **kwargs):\n pass\n\ntest_sig(_T.bar, '(c=3, *, a=1, b=2)')\n\nHere is the same example with instance methods:\n\n# example 2: instance methods\nclass _T():\n def foo(self, a=1, b=2):\n pass\n \n @delegates(foo)\n def bar(self, c=3, **kwargs):\n pass\n\nt = _T()\ntest_sig(t.bar, '(c=3, *, a=1, b=2)')\n\nYou can also delegate between classes. By default, the delegates decorator will delegate to the superclass:\n\nclass BaseFoo:\n def __init__(self, e, c=2): pass\n\n@delegates()# since no argument was passsed here we delegate to the superclass\nclass Foo(BaseFoo):\n def __init__(self, a, b=1, **kwargs): super().__init__(**kwargs)\n\ntest_sig(Foo, '(a, b=1, *, c=2)')\n\n\nsource\n\n\nmethod\n\n method (f)\n\nMark f as a method\nThe method function is used to change a function’s type to a method. In the below example we change the type of a from a function to a method:\n\ndef a(x=2): return x + 1\nassert type(a).__name__ == 'function'\n\na = method(a)\nassert type(a).__name__ == 'method'\n\n\nsource\n\n\nfuncs_kwargs\n\n funcs_kwargs (as_method=False)\n\nReplace methods in cls._methods with those from kwargs\nThe func_kwargs decorator allows you to add a list of functions or methods to an existing class. You must set this list as a class attribute named _methods when defining your class. Additionally, you must incldue the **kwargs argument in the ___init__ method of your class.\nAfter defining your class this way, you can add functions to your class upon instantation as illusrated below.\nFor example, we define class T to allow adding the function b to class T as follows (note that this function is stored as an attribute of T and doesn’t have access to cls or self):\n\n@funcs_kwargs\nclass T:\n _methods=['b'] # allows you to add method b upon instantiation\n def __init__(self, f=1, **kwargs): pass # don't forget to include **kwargs in __init__\n def a(self): return 1\n def b(self): return 2\n \nt = T()\ntest_eq(t.a(), 1)\ntest_eq(t.b(), 2)\n\nBecause we defined the class T this way, the signature of T indicates the option to add the function or method(s) specified in _methods. In this example, b is added to the signature:\n\ntest_sig(T, '(f=1, *, b=None)')\ninspect.signature(T)\n\n<Signature (f=1, *, b=None)>\n\n\nYou can now add the function b to class T upon instantiation:\n\ndef _new_func(): return 5\n\nt = T(b = _new_func)\ntest_eq(t.b(), 5)\n\nIf you try to add a function with a name not listed in _methods it will be ignored. In the below example, the attempt to add a function named a is ignored:\n\nt = T(a = lambda:3)\ntest_eq(t.a(), 1) # the attempt to add a is ignored and uses the original method instead.\n\nNote that you can also add methods not defined in the original class as long it is specified in the _methods attribute:\n\n@funcs_kwargs\nclass T:\n _methods=['c']\n def __init__(self, f=1, **kwargs): pass\n\nt = T(c = lambda: 4)\ntest_eq(t.c(), 4)\n\nUntil now, these examples showed how to add functions stored as an instance attribute without access to self. However, if you need access to self you can set as_method=True in the func_kwargs decorator to add a method instead:\n\ndef _f(self,a=1): return self.num + a # access the num attribute from the instance\n\n@funcs_kwargs(as_method=True)\nclass T: \n _methods=['b']\n num = 5\n \nt = T(b = _f) # adds method b\ntest_eq(t.b(5), 10) # self.num + 5 = 10\n\nHere is an example of how you might use this functionality with inheritence:\n\ndef _f(self,a=1): return self.num * a #multiply instead of add \n\nclass T2(T):\n def __init__(self,num):\n super().__init__(b = _f) # add method b from the super class\n self.num=num\n \nt = T2(num=3)\ntest_eq(t.b(a=5), 15) # 3 * 5 = 15\ntest_sig(T2, '(num)')", + "crumbs": [ + "Meta" + ] + }, + { + "objectID": "script.html", + "href": "script.html", + "title": "Script - CLI", + "section": "", + "text": "Part of fast.ai’s toolkit for delightful developer experiences.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "script.html#overview", + "href": "script.html#overview", + "title": "Script - CLI", + "section": "Overview", + "text": "Overview\nSometimes, you want to create a quick script, either for yourself, or for others. But in Python, that involves a whole lot of boilerplate and ceremony, especially if you want to support command line arguments, provide help, and other niceties. You can use argparse for this purpose, which comes with Python, but it’s complex and verbose.\nfastcore.script makes life easier. There are much fancier modules to help you write scripts (we recommend Python Fire, and Click is also popular), but fastcore.script is very fast and very simple. In fact, it’s <50 lines of code! Basically, it’s just a little wrapper around argparse that uses modern Python features and some thoughtful defaults to get rid of the boilerplate.\nFor full details, see the docs for core.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "script.html#example", + "href": "script.html#example", + "title": "Script - CLI", + "section": "Example", + "text": "Example\nHere’s a complete example (available in examples/test_fastcore.py):\nfrom fastcore.script import *\n@call_parse\ndef main(msg:str, # The message\n upper:bool): # Convert to uppercase?\n \"Print `msg`, optionally converting to uppercase\"\n print(msg.upper() if upper else msg)\nIf you copy that info a file and run it, you’ll see:\n$ examples/test_fastcore.py --help\nusage: test_fastcore.py [-h] [--upper] msg\n\nPrint `msg`, optionally converting to uppercase\n\npositional arguments:\n msg The message\n\noptional arguments:\n -h, --help show this help message and exit\n --upper Convert to uppercase? (default: False)\nAs you see, we didn’t need any if __name__ == \"__main__\", we didn’t have to parse arguments, we just wrote a function, added a decorator to it, and added some annotations to our function’s parameters. As a bonus, we can also use this function directly from a REPL such as Jupyter Notebook - it’s not just for command line scripts!\nYou should provide a default (after the =) for any optional parameters. If you don’t provide a default for a parameter, then it will be a positional parameter.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "script.html#param-annotations", + "href": "script.html#param-annotations", + "title": "Script - CLI", + "section": "Param annotations", + "text": "Param annotations\nIf you want to use the full power of argparse, you can do so by using Param annotations instead of type annotations and docments, like so:\nfrom fastcore.script import *\n@call_parse\ndef main(msg:Param(\"The message\", str),\n upper:Param(\"Convert to uppercase?\", store_true)):\n \"Print `msg`, optionally converting to uppercase\"\n print(msg.upper() if upper else msg)\nIf you use this approach, then each parameter in your function should have an annotation Param(...) (as in the example above). You can pass the following when calling Param: help,type,opt,action,nargs,const,choices,required . Except for opt, all of these are just passed directly to argparse, so you have all the power of that module at your disposal. Generally you’ll want to pass at least help (since this is provided as the help string for that parameter) and type (to ensure that you get the type of data you expect). opt is a bool that defines whether a param is optional or required (positional) - but you’ll generally not need to set this manually, because fastcore.script will set it for you automatically based on default values.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "script.html#setuptools-scripts", + "href": "script.html#setuptools-scripts", + "title": "Script - CLI", + "section": "setuptools scripts", + "text": "setuptools scripts\nThere’s a really nice feature of pip/setuptools that lets you create commandline scripts directly from functions, makes them available in the PATH, and even makes your scripts cross-platform (e.g. in Windows it creates an exe). fastcore.script supports this feature too. The trick to making a function available as a script is to add a console_scripts section to your setup file, of the form: script_name=module:function_name. E.g. in this case we use: test_fastcore.script=fastcore.script.test_cli:main. With this, you can then just type test_fastcore.script at any time, from any directory, and your script will be called (once it’s installed using one of the methods below).\nYou don’t actually have to write a setup.py yourself. Instead, just use nbdev. Then modify settings.ini as appropriate for your module/script. To install your script directly, you can type pip install -e .. Your script, when installed this way (it’s called an editable install), will automatically be up to date even if you edit it - there’s no need to reinstall it after editing. With nbdev you can even make your module and script available for installation directly from pip and conda by running make release.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "script.html#api-details", + "href": "script.html#api-details", + "title": "Script - CLI", + "section": "API details", + "text": "API details\n\nsource\n\nstore_true\n\n store_true ()\n\nPlaceholder to pass to Param for store_true action\n\nsource\n\n\nstore_false\n\n store_false ()\n\nPlaceholder to pass to Param for store_false action\n\nsource\n\n\nbool_arg\n\n bool_arg (v)\n\nUse as type for Param to get bool behavior\n\nsource\n\n\nclean_type_str\n\n clean_type_str (x:str)\n\n\nclass Test: pass\n\ntest_eq(clean_type_str(argparse.ArgumentParser), 'argparse.ArgumentParser')\ntest_eq(clean_type_str(Test), 'Test')\ntest_eq(clean_type_str(int), 'int')\ntest_eq(clean_type_str(float), 'float')\ntest_eq(clean_type_str(store_false), 'store_false')\n\n\nsource\n\n\nParam\n\n Param (help='', type=None, opt=True, action=None, nargs=None, const=None,\n choices=None, required=None, default=None)\n\nA parameter in a function used in anno_parser or call_parse\n\ntest_eq(repr(Param(\"Help goes here\")), '<Help goes here>')\ntest_eq(repr(Param(\"Help\", int)), 'int <Help>')\ntest_eq(repr(Param(help=None, type=int)), 'int')\ntest_eq(repr(Param(help=None, type=None)), '')\n\nEach parameter in your function should have an annotation Param(...). You can pass the following when calling Param: help,type,opt,action,nargs,const,choices,required (i.e. it takes the same parameters as argparse.ArgumentParser.add_argument, plus opt). Except for opt, all of these are just passed directly to argparse, so you have all the power of that module at your disposal. Generally you’ll want to pass at least help (since this is provided as the help string for that parameter) and type (to ensure that you get the type of data you expect).\nopt is a bool that defines whether a param is optional or required (positional) - but you’ll generally not need to set this manually, because fastcore.script will set it for you automatically based on default values. You should provide a default (after the =) for any optional parameters. If you don’t provide a default for a parameter, then it will be a positional parameter.\nParam’s __repr__ also allows for more informative function annotation when looking up the function’s doc using shift+tab. You see the type annotation (if there is one) and the accompanying help documentation with it.\n\ndef f(required:Param(\"Required param\", int),\n a:Param(\"param 1\", bool_arg),\n b:Param(\"param 2\", str)=\"test\"):\n \"my docs\"\n ...\n\n\nhelp(f)\n\nHelp on function f in module __main__:\n\nf(required: int <Required param>, a: bool_arg <param 1>, b: str <param 2> = 'test')\n my docs\n\n\n\n\np = Param(help=\"help\", type=int)\np.set_default(1)\ntest_eq(p.kwargs, {'help': 'help (default: 1)', 'type': int, 'default': 1})\n\n\nsource\n\n\nanno_parser\n\n anno_parser (func, prog:str=None)\n\nLook at params (annotated with Param) in func and return an ArgumentParser\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\nfunc\n\n\nFunction to get arguments from\n\n\nprog\nstr\nNone\nThe name of the program\n\n\n\nThis converts a function with parameter annotations of type Param into an argparse.ArgumentParser object. Function arguments with a default provided are optional, and other arguments are positional.\n\n_en = str_enum('_en', 'aa','bb','cc')\ndef f(required:Param(\"Required param\", int),\n a:Param(\"param 1\", bool_arg),\n b:Param(\"param 2\", str)=\"test\",\n c:Param(\"param 3\", _en)=_en.aa):\n \"my docs\"\n ...\n\np = anno_parser(f, 'progname')\np.print_help()\n\nusage: progname [-h] [--b B] [--c {aa,bb,cc}] required a\n\nmy docs\n\npositional arguments:\n required Required param\n a param 1\n\noptional arguments:\n -h, --help show this help message and exit\n --b B param 2 (default: test)\n --c {aa,bb,cc} param 3 (default: aa)\n\n\nIt also works with type annotations and docments:\n\ndef g(required:int, # Required param\n a:bool_arg, # param 1\n b=\"test\", # param 2\n c:_en=_en.aa): # param 3\n \"my docs\"\n ...\n\np = anno_parser(g, 'progname')\np.print_help()\n\nusage: progname [-h] [--b B] [--c {aa,bb,cc}] required a\n\nmy docs\n\npositional arguments:\n required Required param\n a param 1\n\noptional arguments:\n -h, --help show this help message and exit\n --b B param 2 (default: test)\n --c {aa,bb,cc} param 3 (default: aa)\n\n\n\nsource\n\n\nargs_from_prog\n\n args_from_prog (func, prog)\n\nExtract args from prog\nSometimes it’s convenient to extract arguments from the actual name of the called program. args_from_prog will do this, assuming that names and values of the params are separated by a #. Optionally there can also be a prefix separated by ## (double underscore).\n\nexp = {'a': False, 'b': 'baa'}\ntest_eq(args_from_prog(f, 'foo##a#0#b#baa'), exp)\ntest_eq(args_from_prog(f, 'a#0#b#baa'), exp)\n\n\nsource\n\n\ncall_parse\n\n call_parse (func=None, nested=False)\n\nDecorator to create a simple CLI from func using anno_parser\n\n@call_parse\ndef test_add(\n a:int=0, # param a\n b:int=0 # param 1\n):\n \"Add up `a` and `b`\"\n return a + b\n\ncall_parse decorated functions work as regular functions and also as command-line interface functions.\n\ntest_eq(test_add(1,2), 3)\n\nThis is the main way to use fastcore.script; decorate your function with call_parse, add Param annotations (as shown above) or type annotations and docments, and it can then be used as a script.\nUse the nested keyword argument to create nested parsers, where earlier parsers consume only their known args from sys.argv before later parsers are used. This is useful to create one command line application that executes another. For example:\nmyrunner --keyword 1 script.py -- <script.py args>\nA separating -- after the first application’s args is recommended though not always required, otherwise args may be parsed in unexpected ways. For example:\nmyrunner script.py -h\nwould display myrunner’s help and not script.py’s.", + "crumbs": [ + "Script - CLI" + ] + }, + { + "objectID": "parallel.html", + "href": "parallel.html", + "title": "Parallel", + "section": "", + "text": "from fastcore.test import *\nfrom nbdev.showdoc import *\nfrom fastcore.nb_imports import *\n\n\nsource\n\nthreaded\n\n threaded (process=False)\n\nRun f in a Thread (or Process if process=True), and returns it\n\n@threaded\ndef _1():\n time.sleep(0.05)\n print(\"second\")\n return 5\n\n@threaded\ndef _2():\n time.sleep(0.01)\n print(\"first\")\n\na = _1()\n_2()\ntime.sleep(0.1)\n\nfirst\nsecond\n\n\nAfter the thread is complete, the return value is stored in the result attr.\n\na.result\n\n5\n\n\n\nsource\n\n\nstartthread\n\n startthread (f)\n\nLike threaded, but start thread immediately\n\n@startthread\ndef _():\n time.sleep(0.05)\n print(\"second\")\n\n@startthread\ndef _():\n time.sleep(0.01)\n print(\"first\")\n\ntime.sleep(0.1)\n\nfirst\nsecond\n\n\n\nsource\n\n\nstartproc\n\n startproc (f)\n\nLike threaded(True), but start Process immediately\n\n@startproc\ndef _():\n time.sleep(0.05)\n print(\"second\")\n\n@startproc\ndef _():\n time.sleep(0.01)\n print(\"first\")\n\ntime.sleep(0.1)\n\nfirst\nsecond\n\n\n\nsource\n\n\nparallelable\n\n parallelable (param_name, num_workers, f=None)\n\n\nsource\n\nThreadPoolExecutor\n\n ThreadPoolExecutor (max_workers=4, on_exc=<built-in function print>,\n pause=0, **kwargs)\n\nSame as Python’s ThreadPoolExecutor, except can pass max_workers==0 for serial execution\n\nsource\n\n\nProcessPoolExecutor\n\n ProcessPoolExecutor (max_workers=4, on_exc=<built-in function print>,\n pause=0, mp_context=None, initializer=None,\n initargs=())\n\nSame as Python’s ProcessPoolExecutor, except can pass max_workers==0 for serial execution\n\nsource\n\n\n\nparallel\n\n parallel (f, items, *args, n_workers=4, total=None, progress=None,\n pause=0, method=None, threadpool=False, timeout=None,\n chunksize=1, **kwargs)\n\nApplies func in parallel to items, using n_workers\n\nsource\n\n\nadd_one\n\n add_one (x, a=1)\n\n\ninp,exp = range(50),range(1,51)\n\ntest_eq(parallel(add_one, inp, n_workers=2, progress=False), exp)\ntest_eq(parallel(add_one, inp, threadpool=True, n_workers=2, progress=False), exp)\ntest_eq(parallel(add_one, inp, n_workers=1, a=2), range(2,52))\ntest_eq(parallel(add_one, inp, n_workers=0), exp)\ntest_eq(parallel(add_one, inp, n_workers=0, a=2), range(2,52))\n\nUse the pause parameter to ensure a pause of pause seconds between processes starting. This is in case there are race conditions in starting some process, or to stagger the time each process starts, for example when making many requests to a webserver. Set threadpool=True to use ThreadPoolExecutor instead of ProcessPoolExecutor.\n\nfrom datetime import datetime\n\n\ndef print_time(i): \n time.sleep(random.random()/1000)\n print(i, datetime.now())\n\nparallel(print_time, range(5), n_workers=2, pause=0.25);\n\n0 2022-08-07 05:10:05.999916\n1 2022-08-07 05:10:06.252031\n2 2022-08-07 05:10:06.503603\n3 2022-08-07 05:10:06.755216\n4 2022-08-07 05:10:07.006702\n\n\n\nsource\n\n\nrun_procs\n\n run_procs (f, f_done, args)\n\nCall f for each item in args in parallel, yielding f_done\n\nsource\n\n\nparallel_gen\n\n parallel_gen (cls, items, n_workers=4, **kwargs)\n\nInstantiate cls in n_workers procs & call each on a subset of items in parallel.\n\n# class _C:\n# def __call__(self, o): return ((i+1) for i in o)\n\n# items = range(5)\n\n# res = L(parallel_gen(_C, items, n_workers=0))\n# idxs,dat1 = zip(*res.sorted(itemgetter(0)))\n# test_eq(dat1, range(1,6))\n\n# res = L(parallel_gen(_C, items, n_workers=3))\n# idxs,dat2 = zip(*res.sorted(itemgetter(0)))\n# test_eq(dat2, dat1)\n\ncls is any class with __call__. It will be passed args and kwargs when initialized. Note that n_workers instances of cls are created, one in each process. items are then split in n_workers batches and one is sent to each cls. The function then returns a generator of tuples of item indices and results.\n\nclass TestSleepyBatchFunc:\n \"For testing parallel processes that run at different speeds\"\n def __init__(self): self.a=1\n def __call__(self, batch):\n for k in batch:\n time.sleep(random.random()/4)\n yield k+self.a\n\nx = np.linspace(0,0.99,20)\n\nres = L(parallel_gen(TestSleepyBatchFunc, x, n_workers=2))\ntest_eq(res.sorted().itemgot(1), x+1)\n\n\n\n\n\n\n\n\n\n# #|hide\n# from subprocess import Popen, PIPE\n# # test num_workers > 0 in scripts works when python process start method is spawn\n# process = Popen([\"python\", \"parallel_test.py\"], stdout=PIPE)\n# _, err = process.communicate(timeout=10)\n# exit_code = process.wait()\n# test_eq(exit_code, 0)", + "crumbs": [ + "Parallel" + ] + }, + { + "objectID": "tour.html", + "href": "tour.html", + "title": "A tour of fastcore", + "section": "", + "text": "Here’s a (somewhat) quick tour of a few higlights from fastcore.\n\nDocumentation\nAll fast.ai projects, including this one, are built with nbdev, which is a full literate programming environment built on Jupyter Notebooks. That means that every piece of documentation, including the page you’re reading now, can be accessed as interactive Jupyter notebooks. In fact, you can even grab a link directly to a notebook running interactively on Google Colab - if you want to follow along with this tour, click the link below:\n\ncolab_link('index')\n\nOpen index in Colab\n\n\nThe full docs are available at fastcore.fast.ai. The code in the examples and in all fast.ai libraries follow the fast.ai style guide. In order to support interactive programming, all fast.ai libraries are designed to allow for import * to be used safely, particular by ensuring that __all__ is defined in all packages. In order to see where a function is from, just type it:\n\ncoll_repr\n\n<function fastcore.foundation.coll_repr(c, max_n=10)>\n\n\nFor more details, including a link to the full documentation and source code, use doc, which pops up a window with this information:\ndoc(coll_repr)\n\nThe documentation also contains links to any related functions or classes, which appear like this: coll_repr (in the notebook itself you will just see a word with back-ticks around it; the links are auto-generated in the documentation site). The documentation will generally show one or more examples of use, along with any background context necessary to understand them. As you’ll see, the examples for each function and method are shown as tests, rather than example outputs, so let’s start by explaining that.\n\n\nTesting\nfastcore’s testing module is designed to work well with nbdev, which is a full literate programming environment built on Jupyter Notebooks. That means that your tests, docs, and code all live together in the same notebook. fastcore and nbdev’s approach to testing starts with the premise that all your tests should pass. If one fails, no more tests in a notebook are run.\nTests look like this:\n\ntest_eq(coll_repr(range(1000), 5), '(#1000) [0,1,2,3,4...]')\n\nThat’s an example from the docs for coll_repr. As you see, it’s not showing you the output directly. Here’s what that would look like:\n\ncoll_repr(range(1000), 5)\n\n'(#1000) [0,1,2,3,4...]'\n\n\nSo, the test is actually showing you what the output looks like, because if the function call didn’t return '(#1000) [0,1,2,3,4...]', then the test would have failed.\nSo every test shown in the docs is also showing you the behavior of the library — and vice versa!\nTest functions always start with test_, and then follow with the operation being tested. So test_eq tests for equality (as you saw in the example above). This includes tests for equality of arrays and tensors, lists and generators, and many more:\n\ntest_eq([0,1,2,3], np.arange(4))\n\nWhen a test fails, it prints out information about what was expected:\ntest_eq([0,1,2,3], np.arange(3))\n----\n AssertionError: ==:\n [0, 1, 2, 3]\n [0 1 2]\nIf you want to check that objects are the same type, rather than the just contain the same collection, use test_eq_type.\nYou can test with any comparison function using test, e.g test whether an object is less than:\n\ntest(2, 3, operator.lt)\n\nYou can even test that exceptions are raised:\n\ndef divide_zero(): return 1/0\ntest_fail(divide_zero)\n\n…and test that things are printed to stdout:\n\ntest_stdout(lambda: print('hi'), 'hi')\n\n\n\nFoundations\nfast.ai is unusual in that we often use mixins in our code. Mixins are widely used in many programming languages, such as Ruby, but not so much in Python. We use mixins to attach new behavior to existing libraries, or to allow modules to add new behavior to our own classes, such as in extension modules. One useful example of a mixin we define is Path.ls, which lists a directory and returns an L (an extended list class which we’ll discuss shortly):\n\np = Path('images')\np.ls()\n\n(#6) [Path('images/mnist3.png'),Path('images/att_00000.png'),Path('images/puppy.jpg'),Path('images/att_00005.png'),Path('images/att_00007.png'),Path('images/att_00006.png')]\n\n\nYou can easily add you own mixins with the patch decorator, which takes advantage of Python 3 function annotations to say what class to patch:\n\n@patch\ndef num_items(self:Path): return len(self.ls())\n\np.num_items()\n\n6\n\n\nWe also use **kwargs frequently. In python **kwargs in a parameter like means “put any additional keyword arguments into a dict called kwargs”. Normally, using kwargs makes an API quite difficult to work with, because it breaks things like tab-completion and popup lists of signatures. utils provides use_kwargs and delegates to avoid this problem. See our detailed article on delegation on this topic.\nGetAttr solves a similar problem (and is also discussed in the article linked above): it’s allows you to use Python’s exceptionally useful __getattr__ magic method, but avoids the problem that normally in Python tab-completion and docs break when using this. For instance, you can see here that Python’s dir function, which is used to find the attributes of a python object, finds everything inside the self.default attribute here:\n\nclass Author:\n def __init__(self, name): self.name = name\n\nclass ProductPage(GetAttr):\n _default = 'author'\n def __init__(self,author,price,cost): self.author,self.price,self.cost = author,price,cost\n\np = ProductPage(Author(\"Jeremy\"), 1.50, 0.50)\n[o for o in dir(p) if not o.startswith('_')]\n\n['author', 'cost', 'name', 'price']\n\n\nLooking at that ProductPage example, it’s rather verbose and duplicates a lot of attribute names, which can lead to bugs later if you change them only in one place. fastcore provides store_attr to simplify this common pattern. It also provides basic_repr to give simple objects a useful repr:\n\nclass ProductPage:\n def __init__(self,author,price,cost): store_attr()\n __repr__ = basic_repr('author,price,cost')\n\nProductPage(\"Jeremy\", 1.50, 0.50)\n\n__main__.ProductPage(author='Jeremy', price=1.5, cost=0.5)\n\n\nOne of the most interesting fastcore functions is the funcs_kwargs decorator. This allows class behavior to be modified without sub-classing. This can allow folks that aren’t familiar with object-oriented programming to customize your class more easily. Here’s an example of a class that uses funcs_kwargs:\n\n@funcs_kwargs\nclass T:\n _methods=['some_method']\n def __init__(self, **kwargs): assert not kwargs, f'Passed unknown args: {kwargs}'\n\np = T(some_method = print)\np.some_method(\"hello\")\n\nhello\n\n\nThe assert not kwargs above is used to ensure that the user doesn’t pass an unknown parameter (i.e one that’s not in _methods). fastai uses funcs_kwargs in many places, for instance, you can customize any part of a DataLoader by passing your own methods.\nfastcore also provides many utility functions that make a Python programmer’s life easier, in fastcore.utils. We won’t look at many here, since you can easily look at the docs yourself. To get you started, have a look at the docs for chunked (remember, if you’re in a notebook, type doc(chunked)), which is a handy function for creating lazily generated batches from a collection.\nPython’s ProcessPoolExecutor is extended to allow max_workers to be set to 0, to easily turn off parallel processing. This makes it easy to debug your code in serial, then run it in parallel. It also allows you to pass arguments to your parallel function, and to ensure there’s a pause between calls, in case the process you are running has race conditions. parallel makes parallel processing even easier to use, and even adds an optional progress bar.\n\n\nL\nLike most languages, Python allows for very concise syntax for some very common types, such as list, which can be constructed with [1,2,3]. Perl’s designer Larry Wall explained the reasoning for this kind of syntax:\n\nIn metaphorical honor of Huffman’s compression code that assigns smaller numbers of bits to more common bytes. In terms of syntax, it simply means that commonly used things should be shorter, but you shouldn’t waste short sequences on less common constructs.\n\nOn this basis, fastcore has just one type that has a single letter name: L. The reason for this is that it is designed to be a replacement for list, so we want it to be just as easy to use as [1,2,3]. Here’s how to create that as an L:\n\nL(1,2,3)\n\n(#3) [1,2,3]\n\n\nThe first thing to notice is that an L object includes in its representation its number of elements; that’s the (#3) in the output above. If there’s more than 10 elements, it will automatically truncate the list:\n\np = L.range(20).shuffle()\np\n\n(#20) [5,1,9,10,18,13,6,17,3,16...]\n\n\nL contains many of the same indexing ideas that NumPy’s array does, including indexing with a list of indexes, or a boolean mask list:\n\np[2,4,6]\n\n(#3) [9,18,6]\n\n\nIt also contains other methods used in array, such as L.argwhere:\n\np.argwhere(ge(15))\n\n(#5) [4,7,9,18,19]\n\n\nAs you can see from this example, fastcore also includes a number of features that make a functional style of programming easier, such as a full range of boolean functions (e.g ge, gt, etc) which give the same answer as the functions from Python’s operator module if given two parameters, but return a curried function if given one parameter.\nThere’s too much functionality to show it all here, so be sure to check the docs. Many little things are added that we thought should have been in list in the first place, such as making this do what you’d expect (which is an error with list, but works fine with L):\n\n1 + L(2,3,4)\n\n(#4) [1,2,3,4]\n\n\n\n\nTransforms\nA Transform is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the Transform class provides several mechanisms that make the process of building them easy and flexible (see the docs for information about each of these):\n\nType dispatch\nDispatch over tuples\nReversability\nType propagation\nPreprocessing\nFiltering based on the dataset type\nOrdering\nAppending new behavior with decorators\n\nTransform looks for three special methods, encodes, decodes, and setups, which provide the implementation for __call__, decode, and setup respectively. For instance:\n\nclass A(Transform):\n def encodes(self, x): return x+1\n\nA()(1)\n\n2\n\n\nFor simple transforms like this, you can also use Transform as a decorator:\n\n@Transform\ndef f(x): return x+1\n\nf(1)\n\n2\n\n\nTransforms can be composed into a Pipeline:\n\n@Transform\ndef g(x): return x/2\n\npipe = Pipeline([f,g])\npipe(3)\n\n2.0\n\n\nThe power of Transform and Pipeline is best understood by seeing how they’re used to create a complete data processing pipeline. This is explained in chapter 11 of the fastai book, which is available for free in Jupyter Notebook format.", + "crumbs": [ + "A tour of fastcore" + ] + }, + { + "objectID": "style.html", + "href": "style.html", + "title": "Style", + "section": "", + "text": "Note\n\n\n\nStyled outputs don’t show in Quarto documentation. Please use a notebook editor to correctly view this page.\n\n\n\nsource\n\nStyleCode\n\n StyleCode (name, code, typ)\n\nAn escape sequence for styling terminal text.\nThe primary building block of the S API.\n\nprint(str(StyleCode('blue', 34, 'fg')) + 'hello' + str(StyleCode('default', 39, 'fg')) + ' world')\n\nhello world\n\n\n\nsource\n\n\nStyle\n\n Style (codes=None)\n\nA minimal terminal text styler.\nThe main way to use it is via the exported S object.\n\n\nExported source\nS = Style()\n\n\nWe start with an empty style:\n\nS\n\n<Style: none>\n\n\nDefine a new style by chaining attributes:\n\ns = S.blue.bold.underline\ns\n\n<Style: blue bold underline>\n\n\nYou can see a full list of available styles with auto-complete by typing S . Tab.\nApply a style by calling it with a string:\n\ns('hello world')\n\n'\\x1b[34m\\x1b[1m\\x1b[4mhello world\\x1b[22m\\x1b[24m\\x1b[39m'\n\n\nThat’s a raw string with the underlying escape sequences that tell the terminal how to format text. To see the styled version we have to print it:\n\nprint(s('hello world'))\n\nhello world\n\n\nYou can also nest styles:\n\nprint(S.bold(S.blue('key') + ' = value ') + S.light_gray(' ' + S.underline('# With a comment')) + ' and unstyled text')\n\nkey = value # With a comment and unstyled text\n\n\n\nprint(S.blue('this '+S.bold('is')+' a test'))\n\nthis is a test\n\n\n\nsource\n\n\ndemo\n\n demo ()\n\nDemonstrate all available styles and their codes.\n\ndemo()\n\n 30 black \n 31 red \n 32 green \n 33 yellow \n 34 blue \n 35 magenta \n 36 cyan \n 37 light_gray \n 39 default \n 90 dark_gray \n 91 light_red \n 92 light_green \n 93 light_yellow \n 94 light_blue \n 95 light_magenta \n 96 light_cyan \n 97 white \n 40 black_bg \n 41 red_bg \n 42 green_bg \n 43 yellow_bg \n 44 blue_bg \n 45 magenta_bg \n 46 cyan_bg \n 47 light_gray_bg \n 49 default_bg \n100 dark_gray_bg \n101 light_red_bg \n102 light_green_bg \n103 light_yellow_bg \n104 light_blue_bg \n105 light_magenta_bg\n106 light_cyan_bg \n107 white_bg \n 1 bold \n 2 dim \n 3 italic \n 4 underline \n 5 blink \n 7 invert \n 8 hidden \n 9 strikethrough \n 22 reset_bold \n 22 reset_dim \n 23 reset_italic \n 24 reset_underline \n 25 reset_blink \n 27 reset_invert \n 28 reset_hidden \n 29 reset_strikethrough\n 0 reset", + "crumbs": [ + "Style" + ] + }, + { + "objectID": "basics.html", + "href": "basics.html", + "title": "Basic functionality", + "section": "", + "text": "source\n\n\n\n ifnone (a, b)\n\nb if a is None else a\nSince b if a is None else a is such a common pattern, we wrap it in a function. However, be careful, because python will evaluate both a and b when calling ifnone (which it doesn’t do if using the if version directly).\n\ntest_eq(ifnone(None,1), 1)\ntest_eq(ifnone(2 ,1), 2)\n\n\nsource\n\n\n\n\n maybe_attr (o, attr)\n\ngetattr(o,attr,o)\nReturn the attribute attr for object o. If the attribute doesn’t exist, then return the object o instead.\n\nclass myobj: myattr='foo'\n\ntest_eq(maybe_attr(myobj, 'myattr'), 'foo')\ntest_eq(maybe_attr(myobj, 'another_attr'), myobj)\n\n\nsource\n\n\n\n\n basic_repr (flds=None)\n\nMinimal __repr__\nIn types which provide rich display functionality in Jupyter, their __repr__ is also called in order to provide a fallback text representation. Unfortunately, this includes a memory address which changes on every invocation, making it non-deterministic. This causes diffs to get messy and creates conflicts in git. To fix this, put __repr__=basic_repr() inside your class.\n\nclass SomeClass: __repr__=basic_repr()\nrepr(SomeClass())\n\n'<__main__.SomeClass>'\n\n\nIf you pass a list of attributes (flds) of an object, then this will generate a string with the name of each attribute and its corresponding value. The format of this string is key=value, where key is the name of the attribute, and value is the value of the attribute. For each value, attempt to use the __name__ attribute, otherwise fall back to using the value’s __repr__ when constructing the string.\n\nclass SomeClass:\n a=1\n b='foo'\n __repr__=basic_repr('a,b')\n __name__='some-class'\n\nrepr(SomeClass())\n\n\"__main__.SomeClass(a=1, b='foo')\"\n\n\n\nclass AnotherClass:\n c=SomeClass()\n d='bar'\n __repr__=basic_repr(['c', 'd'])\n\nrepr(AnotherClass())\n\n\"__main__.AnotherClass(c=__main__.SomeClass(a=1, b='foo'), d='bar')\"\n\n\n\nsource\n\n\n\n\n is_array (x)\n\nTrue if x supports __array__ or iloc\n\nis_array(np.array(1)),is_array([1])\n\n(True, False)\n\n\n\nsource\n\n\n\n\n listify (o=None, *rest, use_list=False, match=None)\n\nConvert o to a list\nConversion is designed to “do what you mean”, e.g:\n\ntest_eq(listify('hi'), ['hi'])\ntest_eq(listify(b'hi'), [b'hi'])\ntest_eq(listify(array(1)), [array(1)])\ntest_eq(listify(1), [1])\ntest_eq(listify([1,2]), [1,2])\ntest_eq(listify(range(3)), [0,1,2])\ntest_eq(listify(None), [])\ntest_eq(listify(1,2), [1,2])\n\n\narr = np.arange(9).reshape(3,3)\nlistify(arr)\n\n[array([[0, 1, 2],\n [3, 4, 5],\n [6, 7, 8]])]\n\n\n\nlistify(array([1,2]))\n\n[array([1, 2])]\n\n\nGenerators are turned into lists too:\n\ngen = (o for o in range(3))\ntest_eq(listify(gen), [0,1,2])\n\nUse match to provide a length to match:\n\ntest_eq(listify(1,match=3), [1,1,1])\n\nIf match is a sequence, it’s length is used:\n\ntest_eq(listify(1,match=range(3)), [1,1,1])\n\nIf the listified item is not of length 1, it must be the same length as match:\n\ntest_eq(listify([1,1,1],match=3), [1,1,1])\ntest_fail(lambda: listify([1,1],match=3))\n\n\nsource\n\n\n\n\n tuplify (o, use_list=False, match=None)\n\nMake o a tuple\n\ntest_eq(tuplify(None),())\ntest_eq(tuplify([1,2,3]),(1,2,3))\ntest_eq(tuplify(1,match=[1,2,3]),(1,1,1))\n\n\nsource\n\n\n\n\n true (x)\n\nTest whether x is truthy; collections with >0 elements are considered True\n\n[(o,true(o)) for o in\n (array(0),array(1),array([0]),array([0,1]),1,0,'',None)]\n\n[(array(0), False),\n (array(1), True),\n (array([0]), True),\n (array([0, 1]), True),\n (1, True),\n (0, False),\n ('', False),\n (None, False)]\n\n\n\nsource\n\n\n\n\n NullType ()\n\nAn object that is False and can be called, chained, and indexed\n\nbool(null.hi().there[3])\n\nFalse\n\n\n\nsource\n\n\n\n\n tonull (x)\n\nConvert None to null\n\nbool(tonull(None).hi().there[3])\n\nFalse\n\n\n\nsource\n\n\n\n\n get_class (nm, *fld_names, sup=None, doc=None, funcs=None, anno=None,\n **flds)\n\nDynamically create a class, optionally inheriting from sup, containing fld_names\n\n_t = get_class('_t', 'a', b=2, anno={'b':int})\nt = _t()\ntest_eq(t.a, None)\ntest_eq(t.b, 2)\nt = _t(1, b=3)\ntest_eq(t.a, 1)\ntest_eq(t.b, 3)\nt = _t(1, 3)\ntest_eq(t.a, 1)\ntest_eq(t.b, 3)\ntest_eq(t, pickle.loads(pickle.dumps(t)))\ntest_eq(_t.__annotations__, {'b':int, 'a':typing.Any})\nrepr(t)\n\n'__main__._t(a=1, b=3)'\n\n\nMost often you’ll want to call mk_class, since it adds the class to your module. See mk_class for more details and examples of use (which also apply to get_class).\n\nsource\n\n\n\n\n mk_class (nm, *fld_names, sup=None, doc=None, funcs=None, mod=None,\n anno=None, **flds)\n\nCreate a class using get_class and add to the caller’s module\nAny kwargs will be added as class attributes, and sup is an optional (tuple of) base classes.\n\nmk_class('_t', a=1, sup=dict)\nt = _t()\ntest_eq(t.a, 1)\nassert(isinstance(t,dict))\n\nA __init__ is provided that sets attrs for any kwargs, and for any args (matching by position to fields), along with a __repr__ which prints all attrs. The docstring is set to doc. You can pass funcs which will be added as attrs with the function names.\n\ndef foo(self): return 1\nmk_class('_t', 'a', sup=dict, doc='test doc', funcs=foo)\n\nt = _t(3, b=2)\ntest_eq(t.a, 3)\ntest_eq(t.b, 2)\ntest_eq(t.foo(), 1)\ntest_eq(t.__doc__, 'test doc')\nt\n\n{}\n\n\n\nsource\n\n\n\n\n wrap_class (nm, *fld_names, sup=None, doc=None, funcs=None, **flds)\n\nDecorator: makes function a method of a new class nm passing parameters to mk_class\n\n@wrap_class('_t', a=2)\ndef bar(self,x): return x+1\n\nt = _t()\ntest_eq(t.a, 2)\ntest_eq(t.bar(3), 4)\n\n\nsource\n\n\n\n ignore_exceptions ()\n\nContext manager to ignore exceptions\n\nwith ignore_exceptions(): \n # Exception will be ignored\n raise Exception\n\n\nsource\n\n\n\n\n\n exec_local (code, var_name)\n\nCall exec on code and return the var var_name\n\ntest_eq(exec_local(\"a=1\", \"a\"), 1)\n\n\nsource\n\n\n\n\n risinstance (types, obj=None)\n\nCurried isinstance but with args reversed\n\nassert risinstance(int, 1)\nassert not risinstance(str, 0)\nassert risinstance(int)(1)\n\ntypes can also be strings:\n\nassert risinstance(('str','int'), 'a')\nassert risinstance('str', 'a')\nassert not risinstance('int', 'a')\n\n\nsource\n\n\n\n\n ver2tuple (v:str)\n\n\ntest_eq(ver2tuple('3.8.1'), (3,8,1))\ntest_eq(ver2tuple('3.1'), (3,1,0))\ntest_eq(ver2tuple('3.'), (3,0,0))\ntest_eq(ver2tuple('3'), (3,0,0))", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#basics", + "href": "basics.html#basics", + "title": "Basic functionality", + "section": "", + "text": "source\n\n\n\n ifnone (a, b)\n\nb if a is None else a\nSince b if a is None else a is such a common pattern, we wrap it in a function. However, be careful, because python will evaluate both a and b when calling ifnone (which it doesn’t do if using the if version directly).\n\ntest_eq(ifnone(None,1), 1)\ntest_eq(ifnone(2 ,1), 2)\n\n\nsource\n\n\n\n\n maybe_attr (o, attr)\n\ngetattr(o,attr,o)\nReturn the attribute attr for object o. If the attribute doesn’t exist, then return the object o instead.\n\nclass myobj: myattr='foo'\n\ntest_eq(maybe_attr(myobj, 'myattr'), 'foo')\ntest_eq(maybe_attr(myobj, 'another_attr'), myobj)\n\n\nsource\n\n\n\n\n basic_repr (flds=None)\n\nMinimal __repr__\nIn types which provide rich display functionality in Jupyter, their __repr__ is also called in order to provide a fallback text representation. Unfortunately, this includes a memory address which changes on every invocation, making it non-deterministic. This causes diffs to get messy and creates conflicts in git. To fix this, put __repr__=basic_repr() inside your class.\n\nclass SomeClass: __repr__=basic_repr()\nrepr(SomeClass())\n\n'<__main__.SomeClass>'\n\n\nIf you pass a list of attributes (flds) of an object, then this will generate a string with the name of each attribute and its corresponding value. The format of this string is key=value, where key is the name of the attribute, and value is the value of the attribute. For each value, attempt to use the __name__ attribute, otherwise fall back to using the value’s __repr__ when constructing the string.\n\nclass SomeClass:\n a=1\n b='foo'\n __repr__=basic_repr('a,b')\n __name__='some-class'\n\nrepr(SomeClass())\n\n\"__main__.SomeClass(a=1, b='foo')\"\n\n\n\nclass AnotherClass:\n c=SomeClass()\n d='bar'\n __repr__=basic_repr(['c', 'd'])\n\nrepr(AnotherClass())\n\n\"__main__.AnotherClass(c=__main__.SomeClass(a=1, b='foo'), d='bar')\"\n\n\n\nsource\n\n\n\n\n is_array (x)\n\nTrue if x supports __array__ or iloc\n\nis_array(np.array(1)),is_array([1])\n\n(True, False)\n\n\n\nsource\n\n\n\n\n listify (o=None, *rest, use_list=False, match=None)\n\nConvert o to a list\nConversion is designed to “do what you mean”, e.g:\n\ntest_eq(listify('hi'), ['hi'])\ntest_eq(listify(b'hi'), [b'hi'])\ntest_eq(listify(array(1)), [array(1)])\ntest_eq(listify(1), [1])\ntest_eq(listify([1,2]), [1,2])\ntest_eq(listify(range(3)), [0,1,2])\ntest_eq(listify(None), [])\ntest_eq(listify(1,2), [1,2])\n\n\narr = np.arange(9).reshape(3,3)\nlistify(arr)\n\n[array([[0, 1, 2],\n [3, 4, 5],\n [6, 7, 8]])]\n\n\n\nlistify(array([1,2]))\n\n[array([1, 2])]\n\n\nGenerators are turned into lists too:\n\ngen = (o for o in range(3))\ntest_eq(listify(gen), [0,1,2])\n\nUse match to provide a length to match:\n\ntest_eq(listify(1,match=3), [1,1,1])\n\nIf match is a sequence, it’s length is used:\n\ntest_eq(listify(1,match=range(3)), [1,1,1])\n\nIf the listified item is not of length 1, it must be the same length as match:\n\ntest_eq(listify([1,1,1],match=3), [1,1,1])\ntest_fail(lambda: listify([1,1],match=3))\n\n\nsource\n\n\n\n\n tuplify (o, use_list=False, match=None)\n\nMake o a tuple\n\ntest_eq(tuplify(None),())\ntest_eq(tuplify([1,2,3]),(1,2,3))\ntest_eq(tuplify(1,match=[1,2,3]),(1,1,1))\n\n\nsource\n\n\n\n\n true (x)\n\nTest whether x is truthy; collections with >0 elements are considered True\n\n[(o,true(o)) for o in\n (array(0),array(1),array([0]),array([0,1]),1,0,'',None)]\n\n[(array(0), False),\n (array(1), True),\n (array([0]), True),\n (array([0, 1]), True),\n (1, True),\n (0, False),\n ('', False),\n (None, False)]\n\n\n\nsource\n\n\n\n\n NullType ()\n\nAn object that is False and can be called, chained, and indexed\n\nbool(null.hi().there[3])\n\nFalse\n\n\n\nsource\n\n\n\n\n tonull (x)\n\nConvert None to null\n\nbool(tonull(None).hi().there[3])\n\nFalse\n\n\n\nsource\n\n\n\n\n get_class (nm, *fld_names, sup=None, doc=None, funcs=None, anno=None,\n **flds)\n\nDynamically create a class, optionally inheriting from sup, containing fld_names\n\n_t = get_class('_t', 'a', b=2, anno={'b':int})\nt = _t()\ntest_eq(t.a, None)\ntest_eq(t.b, 2)\nt = _t(1, b=3)\ntest_eq(t.a, 1)\ntest_eq(t.b, 3)\nt = _t(1, 3)\ntest_eq(t.a, 1)\ntest_eq(t.b, 3)\ntest_eq(t, pickle.loads(pickle.dumps(t)))\ntest_eq(_t.__annotations__, {'b':int, 'a':typing.Any})\nrepr(t)\n\n'__main__._t(a=1, b=3)'\n\n\nMost often you’ll want to call mk_class, since it adds the class to your module. See mk_class for more details and examples of use (which also apply to get_class).\n\nsource\n\n\n\n\n mk_class (nm, *fld_names, sup=None, doc=None, funcs=None, mod=None,\n anno=None, **flds)\n\nCreate a class using get_class and add to the caller’s module\nAny kwargs will be added as class attributes, and sup is an optional (tuple of) base classes.\n\nmk_class('_t', a=1, sup=dict)\nt = _t()\ntest_eq(t.a, 1)\nassert(isinstance(t,dict))\n\nA __init__ is provided that sets attrs for any kwargs, and for any args (matching by position to fields), along with a __repr__ which prints all attrs. The docstring is set to doc. You can pass funcs which will be added as attrs with the function names.\n\ndef foo(self): return 1\nmk_class('_t', 'a', sup=dict, doc='test doc', funcs=foo)\n\nt = _t(3, b=2)\ntest_eq(t.a, 3)\ntest_eq(t.b, 2)\ntest_eq(t.foo(), 1)\ntest_eq(t.__doc__, 'test doc')\nt\n\n{}\n\n\n\nsource\n\n\n\n\n wrap_class (nm, *fld_names, sup=None, doc=None, funcs=None, **flds)\n\nDecorator: makes function a method of a new class nm passing parameters to mk_class\n\n@wrap_class('_t', a=2)\ndef bar(self,x): return x+1\n\nt = _t()\ntest_eq(t.a, 2)\ntest_eq(t.bar(3), 4)\n\n\nsource\n\n\n\n ignore_exceptions ()\n\nContext manager to ignore exceptions\n\nwith ignore_exceptions(): \n # Exception will be ignored\n raise Exception\n\n\nsource\n\n\n\n\n\n exec_local (code, var_name)\n\nCall exec on code and return the var var_name\n\ntest_eq(exec_local(\"a=1\", \"a\"), 1)\n\n\nsource\n\n\n\n\n risinstance (types, obj=None)\n\nCurried isinstance but with args reversed\n\nassert risinstance(int, 1)\nassert not risinstance(str, 0)\nassert risinstance(int)(1)\n\ntypes can also be strings:\n\nassert risinstance(('str','int'), 'a')\nassert risinstance('str', 'a')\nassert not risinstance('int', 'a')\n\n\nsource\n\n\n\n\n ver2tuple (v:str)\n\n\ntest_eq(ver2tuple('3.8.1'), (3,8,1))\ntest_eq(ver2tuple('3.1'), (3,1,0))\ntest_eq(ver2tuple('3.'), (3,0,0))\ntest_eq(ver2tuple('3'), (3,0,0))", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#noop", + "href": "basics.html#noop", + "title": "Basic functionality", + "section": "NoOp", + "text": "NoOp\nThese are used when you need a pass-through function.\n\n\nnoop\n\n noop (x=None, *args, **kwargs)\n\nDo nothing\n\nnoop()\ntest_eq(noop(1),1)\n\n\n\n\nnoops\n\n noops (x=None, *args, **kwargs)\n\nDo nothing (method)\n\nclass _t: foo=noops\ntest_eq(_t().foo(1),1)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#infinite-lists", + "href": "basics.html#infinite-lists", + "title": "Basic functionality", + "section": "Infinite Lists", + "text": "Infinite Lists\nThese lists are useful for things like padding an array or adding index column(s) to arrays.\nInf defines the following properties:\n\ncount: itertools.count()\nzeros: itertools.cycle([0])\nones : itertools.cycle([1])\nnones: itertools.cycle([None])\n\n\ntest_eq([o for i,o in zip(range(5), Inf.count)],\n [0, 1, 2, 3, 4])\n\ntest_eq([o for i,o in zip(range(5), Inf.zeros)],\n [0]*5)\n\ntest_eq([o for i,o in zip(range(5), Inf.ones)],\n [1]*5)\n\ntest_eq([o for i,o in zip(range(5), Inf.nones)],\n [None]*5)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#operator-functions", + "href": "basics.html#operator-functions", + "title": "Basic functionality", + "section": "Operator Functions", + "text": "Operator Functions\n\nsource\n\nin_\n\n in_ (x, a)\n\nTrue if x in a\n\n# test if element is in another\nassert in_('c', ('b', 'c', 'a'))\nassert in_(4, [2,3,4,5])\nassert in_('t', 'fastai')\ntest_fail(in_('h', 'fastai'))\n\n# use in_ as a partial\nassert in_('fastai')('t')\nassert in_([2,3,4,5])(4)\ntest_fail(in_('fastai')('h'))\n\nIn addition to in_, the following functions are provided matching the behavior of the equivalent versions in operator: lt gt le ge eq ne add sub mul truediv is_ is_not mod.\n\nlt(3,5),gt(3,5),is_(None,None),in_(0,[1,2]),mod(3,2)\n\n(True, False, True, False, 1)\n\n\nSimilarly to _in, they also have additional functionality: if you only pass one param, they return a partial function that passes that param as the second positional parameter.\n\nlt(5)(3),gt(5)(3),is_(None)(None),in_([1,2])(0),mod(2)(3)\n\n(True, False, True, False, 1)\n\n\n\nsource\n\n\nret_true\n\n ret_true (*args, **kwargs)\n\nPredicate: always True\n\nassert ret_true(1,2,3)\nassert ret_true(False)\n\n\nsource\n\n\nret_false\n\n ret_false (*args, **kwargs)\n\nPredicate: always False\n\nsource\n\n\nstop\n\n stop (e=<class 'StopIteration'>)\n\nRaises exception e (by default StopIteration)\n\nsource\n\n\ngen\n\n gen (func, seq, cond=<function ret_true>)\n\nLike (func(o) for o in seq if cond(func(o))) but handles StopIteration\n\ntest_eq(gen(noop, Inf.count, lt(5)),\n range(5))\ntest_eq(gen(operator.neg, Inf.count, gt(-5)),\n [0,-1,-2,-3,-4])\ntest_eq(gen(lambda o:o if o<5 else stop(), Inf.count),\n range(5))\n\n\nsource\n\n\nchunked\n\n chunked (it, chunk_sz=None, drop_last=False, n_chunks=None)\n\nReturn batches from iterator it of size chunk_sz (or return n_chunks total)\nNote that you must pass either chunk_sz, or n_chunks, but not both.\n\nt = list(range(10))\ntest_eq(chunked(t,3), [[0,1,2], [3,4,5], [6,7,8], [9]])\ntest_eq(chunked(t,3,True), [[0,1,2], [3,4,5], [6,7,8], ])\n\nt = map(lambda o:stop() if o==6 else o, Inf.count)\ntest_eq(chunked(t,3), [[0, 1, 2], [3, 4, 5]])\nt = map(lambda o:stop() if o==7 else o, Inf.count)\ntest_eq(chunked(t,3), [[0, 1, 2], [3, 4, 5], [6]])\n\nt = np.arange(10)\ntest_eq(chunked(t,3), [[0,1,2], [3,4,5], [6,7,8], [9]])\ntest_eq(chunked(t,3,True), [[0,1,2], [3,4,5], [6,7,8], ])\n\ntest_eq(chunked([], 3), [])\ntest_eq(chunked([], n_chunks=3), [])\n\n\nsource\n\n\notherwise\n\n otherwise (x, tst, y)\n\ny if tst(x) else x\n\ntest_eq(otherwise(2+1, gt(3), 4), 3)\ntest_eq(otherwise(2+1, gt(2), 4), 4)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#attribute-helpers", + "href": "basics.html#attribute-helpers", + "title": "Basic functionality", + "section": "Attribute Helpers", + "text": "Attribute Helpers\nThese functions reduce boilerplate when setting or manipulating attributes or properties of objects.\n\nsource\n\ncustom_dir\n\n custom_dir (c, add)\n\nImplement custom __dir__, adding add to cls\ncustom_dir allows you extract the __dict__ property of a class and appends the list add to it.\n\nclass _T: \n def f(): pass\n\ns = custom_dir(_T(), add=['foo', 'bar'])\nassert {'foo', 'bar', 'f'}.issubset(s)\n\n\nsource\n\n\nAttrDict\ndict subclass that also provides access to keys as attrs\n\nd = AttrDict(a=1,b=\"two\")\ntest_eq(d.a, 1)\ntest_eq(d['b'], 'two')\ntest_eq(d.get('c','nope'), 'nope')\nd.b = 2\ntest_eq(d.b, 2)\ntest_eq(d['b'], 2)\nd['b'] = 3\ntest_eq(d['b'], 3)\ntest_eq(d.b, 3)\nassert 'a' in dir(d)\n\nAttrDict will pretty print in Jupyter Notebooks:\n\n_test_dict = {'a':1, 'b': {'c':1, 'd':2}, 'c': {'c':1, 'd':2}, 'd': {'c':1, 'd':2},\n 'e': {'c':1, 'd':2}, 'f': {'c':1, 'd':2, 'e': 4, 'f':[1,2,3,4,5]}}\nAttrDict(_test_dict)\n\n{ 'a': 1,\n 'b': {'c': 1, 'd': 2},\n 'c': {'c': 1, 'd': 2},\n 'd': {'c': 1, 'd': 2},\n 'e': {'c': 1, 'd': 2},\n 'f': {'c': 1, 'd': 2, 'e': 4, 'f': [1, 2, 3, 4, 5]}}\n\n\n\nsource\n\n\nNS\nSimpleNamespace subclass that also adds iter and dict support\nThis is very similar to AttrDict, but since it starts with SimpleNamespace, it has some differences in behavior. You can use it just like SimpleNamespace:\n\nd = NS(**_test_dict)\nd\n\nnamespace(a=1,\n b={'c': 1, 'd': 2},\n c={'c': 1, 'd': 2},\n d={'c': 1, 'd': 2},\n e={'c': 1, 'd': 2},\n f={'c': 1, 'd': 2, 'e': 4, 'f': [1, 2, 3, 4, 5]})\n\n\n…but you can also index it to get/set:\n\nd['a']\n\n1\n\n\n…and iterate t:\n\nlist(d)\n\n['a', 'b', 'c', 'd', 'e', 'f']\n\n\n\nsource\n\n\nget_annotations_ex\n\n get_annotations_ex (obj, globals=None, locals=None)\n\nBackport of py3.10 get_annotations that returns globals/locals\nIn Python 3.10 inspect.get_annotations was added. However previous versions of Python are unable to evaluate type annotations correctly if from future import __annotations__ is used. Furthermore, all annotations are evaluated, even if only some subset are needed. get_annotations_ex provides the same functionality as inspect.get_annotations, but works on earlier versions of Python, and returns the globals and locals needed to evaluate types.\n\nsource\n\n\neval_type\n\n eval_type (t, glb, loc)\n\neval a type or collection of types, if needed, for annotations in py3.10+\nIn py3.10, or if from future import __annotations__ is used, a is a str:\n\nclass _T2a: pass\ndef func(a: _T2a): pass\nann,glb,loc = get_annotations_ex(func)\n\neval_type(ann['a'], glb, loc)\n\n__main__._T2a\n\n\n| is supported for defining Union types when using eval_type even for python versions prior to 3.9:\n\nclass _T2b: pass\ndef func(a: _T2a|_T2b): pass\nann,glb,loc = get_annotations_ex(func)\n\neval_type(ann['a'], glb, loc)\n\ntyping.Union[__main__._T2a, __main__._T2b]\n\n\n\nsource\n\n\ntype_hints\n\n type_hints (f)\n\nLike typing.get_type_hints but returns {} if not allowed type\nBelow is a list of allowed types for type hints in python:\n\nlist(typing._allowed_types)\n\n[function,\n builtin_function_or_method,\n method,\n module,\n wrapper_descriptor,\n method-wrapper,\n method_descriptor]\n\n\nFor example, type func is allowed so type_hints returns the same value as typing.get_hints:\n\ndef f(a:int)->bool: ... # a function with type hints (allowed)\nexp = {'a':int,'return':bool}\ntest_eq(type_hints(f), typing.get_type_hints(f))\ntest_eq(type_hints(f), exp)\n\nHowever, class is not an allowed type, so type_hints returns {}:\n\nclass _T:\n def __init__(self, a:int=0)->bool: ...\nassert not type_hints(_T)\n\n\nsource\n\n\nannotations\n\n annotations (o)\n\nAnnotations for o, or type(o)\nThis supports a wider range of situations than type_hints, by checking type() and __init__ for annotations too:\n\nfor o in _T,_T(),_T.__init__,f: test_eq(annotations(o), exp)\nassert not annotations(int)\nassert not annotations(print)\n\n\nsource\n\n\nanno_ret\n\n anno_ret (func)\n\nGet the return annotation of func\n\ndef f(x) -> float: return x\ntest_eq(anno_ret(f), float)\n\ndef f(x) -> typing.Tuple[float,float]: return x\nassert anno_ret(f)==typing.Tuple[float,float]\n\nIf your return annotation is None, anno_ret will return NoneType (and not None):\n\ndef f(x) -> None: return x\n\ntest_eq(anno_ret(f), NoneType)\nassert anno_ret(f) is not None # returns NoneType instead of None\n\nIf your function does not have a return type, or if you pass in None instead of a function, then anno_ret returns None:\n\ndef f(x): return x\n\ntest_eq(anno_ret(f), None)\ntest_eq(anno_ret(None), None) # instead of passing in a func, pass in None\n\n\nsource\n\n\nsignature_ex\n\n signature_ex (obj, eval_str:bool=False)\n\nBackport of inspect.signature(..., eval_str=True to <py310\n\nsource\n\n\nunion2tuple\n\n union2tuple (t)\n\n\ntest_eq(union2tuple(Union[int,str]), (int,str))\ntest_eq(union2tuple(int), int)\nassert union2tuple(Tuple[int,str])==Tuple[int,str]\ntest_eq(union2tuple((int,str)), (int,str))\nif UnionType: test_eq(union2tuple(int|str), (int,str))\n\n\nsource\n\n\nargnames\n\n argnames (f, frame=False)\n\nNames of arguments to function or frame f\n\ntest_eq(argnames(f), ['x'])\n\n\nsource\n\n\nwith_cast\n\n with_cast (f)\n\nDecorator which uses any parameter annotations as preprocessing functions\n\n@with_cast\ndef _f(a, b:Path, c:str='', d=0): return (a,b,c,d)\n\ntest_eq(_f(1, '.', 3), (1,Path('.'),'3',0))\ntest_eq(_f(1, '.'), (1,Path('.'),'',0))\n\n@with_cast\ndef _g(a:int=0)->str: return a\n\ntest_eq(_g(4.0), '4')\ntest_eq(_g(4.4), '4')\ntest_eq(_g(2), '2')\n\n\nsource\n\n\nstore_attr\n\n store_attr (names=None, but='', cast=False, store_args=None, **attrs)\n\nStore params named in comma-separated names from calling context into attrs in self\nIn it’s most basic form, you can use store_attr to shorten code like this:\n\nclass T:\n def __init__(self, a,b,c): self.a,self.b,self.c = a,b,c\n\n…to this:\n\nclass T:\n def __init__(self, a,b,c): store_attr('a,b,c', self)\n\nThis class behaves as if we’d used the first form:\n\nt = T(1,c=2,b=3)\nassert t.a==1 and t.b==3 and t.c==2\n\nIn addition, it stores the attrs as a dict in __stored_args__, which you can use for display, logging, and so forth.\n\ntest_eq(t.__stored_args__, {'a':1, 'b':3, 'c':2})\n\nSince you normally want to use the first argument (often called self) for storing attributes, it’s optional:\n\nclass T:\n def __init__(self, a,b,c:str): store_attr('a,b,c')\n\nt = T(1,c=2,b=3)\nassert t.a==1 and t.b==3 and t.c==2\n\nWith cast=True any parameter annotations will be used as preprocessing functions for the corresponding arguments:\n\nclass T:\n def __init__(self, a:listify, b, c:str): store_attr('a,b,c', cast=True)\n\nt = T(1,c=2,b=3)\nassert t.a==[1] and t.b==3 and t.c=='2'\n\nYou can inherit from a class using store_attr, and just call it again to add in any new attributes added in the derived class:\n\nclass T2(T):\n def __init__(self, d, **kwargs):\n super().__init__(**kwargs)\n store_attr('d')\n\nt = T2(d=1,a=2,b=3,c=4)\nassert t.a==2 and t.b==3 and t.c==4 and t.d==1\n\nYou can skip passing a list of attrs to store. In this case, all arguments passed to the method are stored:\n\nclass T:\n def __init__(self, a,b,c): store_attr()\n\nt = T(1,c=2,b=3)\nassert t.a==1 and t.b==3 and t.c==2\n\n\nclass T4(T):\n def __init__(self, d, **kwargs):\n super().__init__(**kwargs)\n store_attr()\n\nt = T4(4, a=1,c=2,b=3)\nassert t.a==1 and t.b==3 and t.c==2 and t.d==4\n\n\nclass T4:\n def __init__(self, *, a: int, b: float = 1):\n store_attr()\n \nt = T4(a=3)\nassert t.a==3 and t.b==1\nt = T4(a=3, b=2)\nassert t.a==3 and t.b==2\n\nYou can skip some attrs by passing but:\n\nclass T:\n def __init__(self, a,b,c): store_attr(but='a')\n\nt = T(1,c=2,b=3)\nassert t.b==3 and t.c==2\nassert not hasattr(t,'a')\n\nYou can also pass keywords to store_attr, which is identical to setting the attrs directly, but also stores them in __stored_args__.\n\nclass T:\n def __init__(self): store_attr(a=1)\n\nt = T()\nassert t.a==1\n\nYou can also use store_attr inside functions.\n\ndef create_T(a, b):\n t = SimpleNamespace()\n store_attr(self=t)\n return t\n\nt = create_T(a=1, b=2)\nassert t.a==1 and t.b==2\n\n\nsource\n\n\nattrdict\n\n attrdict (o, *ks, default=None)\n\nDict from each k in ks to getattr(o,k)\n\nclass T:\n def __init__(self, a,b,c): store_attr()\n\nt = T(1,c=2,b=3)\ntest_eq(attrdict(t,'b','c'), {'b':3, 'c':2})\n\n\nsource\n\n\nproperties\n\n properties (cls, *ps)\n\nChange attrs in cls with names in ps to properties\n\nclass T:\n def a(self): return 1\n def b(self): return 2\nproperties(T,'a')\n\ntest_eq(T().a,1)\ntest_eq(T().b(),2)\n\n\nsource\n\n\ncamel2words\n\n camel2words (s, space=' ')\n\nConvert CamelCase to ‘spaced words’\n\ntest_eq(camel2words('ClassAreCamel'), 'Class Are Camel')\n\n\nsource\n\n\ncamel2snake\n\n camel2snake (name)\n\nConvert CamelCase to snake_case\n\ntest_eq(camel2snake('ClassAreCamel'), 'class_are_camel')\ntest_eq(camel2snake('Already_Snake'), 'already__snake')\n\n\nsource\n\n\nsnake2camel\n\n snake2camel (s)\n\nConvert snake_case to CamelCase\n\ntest_eq(snake2camel('a_b_cc'), 'ABCc')\n\n\nsource\n\n\nclass2attr\n\n class2attr (cls_name)\n\nReturn the snake-cased name of the class; strip ending cls_name if it exists.\n\nclass Parent:\n @property\n def name(self): return class2attr(self, 'Parent')\n\nclass ChildOfParent(Parent): pass\nclass ParentChildOf(Parent): pass\n\np = Parent()\ncp = ChildOfParent()\ncp2 = ParentChildOf()\n\ntest_eq(p.name, 'parent')\ntest_eq(cp.name, 'child_of')\ntest_eq(cp2.name, 'parent_child_of')\n\n\nsource\n\n\ngetcallable\n\n getcallable (o, attr)\n\nCalls getattr with a default of noop\n\nclass Math:\n def addition(self,a,b): return a+b\n\nm = Math()\n\ntest_eq(getcallable(m, \"addition\")(a=1,b=2), 3)\ntest_eq(getcallable(m, \"subtraction\")(a=1,b=2), None)\n\n\nsource\n\n\ngetattrs\n\n getattrs (o, *attrs, default=None)\n\nList of all attrs in o\n\nfrom fractions import Fraction\n\n\ngetattrs(Fraction(1,2), 'numerator', 'denominator')\n\n[1, 2]\n\n\n\nsource\n\n\nhasattrs\n\n hasattrs (o, attrs)\n\nTest whether o contains all attrs\n\nassert hasattrs(1,('imag','real'))\nassert not hasattrs(1,('imag','foo'))\n\n\nsource\n\n\nsetattrs\n\n setattrs (dest, flds, src)\n\n\nd = dict(a=1,bb=\"2\",ignore=3)\no = SimpleNamespace()\nsetattrs(o, \"a,bb\", d)\ntest_eq(o.a, 1)\ntest_eq(o.bb, \"2\")\n\n\nd = SimpleNamespace(a=1,bb=\"2\",ignore=3)\no = SimpleNamespace()\nsetattrs(o, \"a,bb\", d)\ntest_eq(o.a, 1)\ntest_eq(o.bb, \"2\")\n\n\nsource\n\n\ntry_attrs\n\n try_attrs (obj, *attrs)\n\nReturn first attr that exists in obj\n\ntest_eq(try_attrs(1, 'real'), 1)\ntest_eq(try_attrs(1, 'foobar', 'real'), 1)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#attribute-delegation", + "href": "basics.html#attribute-delegation", + "title": "Basic functionality", + "section": "Attribute Delegation", + "text": "Attribute Delegation\n\nsource\n\nGetAttrBase\n\n GetAttrBase ()\n\nBasic delegation of __getattr__ and __dir__\n\nsource\n\nGetAttr\n\n GetAttr ()\n\nInherit from this to have all attr accesses in self._xtra passed down to self.default\nInherit from GetAttr to have attr access passed down to an instance attribute. This makes it easy to create composites that don’t require callers to know about their components. For a more detailed discussion of how this works as well as relevant context, we suggest reading the delegated composition section of this blog article.\nYou can customise the behaviour of GetAttr in subclasses via; - _default - By default, this is set to 'default', so attr access is passed down to self.default - _default can be set to the name of any instance attribute that does not start with dunder __ - _xtra - By default, this is None, so all attr access is passed down - You can limit which attrs get passed down by setting _xtra to a list of attribute names\nTo illuminate the utility of GetAttr, suppose we have the following two classes, _WebPage which is a superclass of _ProductPage, which we wish to compose like so:\n\nclass _WebPage:\n def __init__(self, title, author=\"Jeremy\"):\n self.title,self.author = title,author\n\nclass _ProductPage:\n def __init__(self, page, price): self.page,self.price = page,price\n \npage = _WebPage('Soap', author=\"Sylvain\")\np = _ProductPage(page, 15.0)\n\nHow do we make it so we can just write p.author, instead of p.page.author to access the author attribute? We can use GetAttr, of course! First, we subclass GetAttr when defining _ProductPage. Next, we set self.default to the object whose attributes we want to be able to access directly, which in this case is the page argument passed on initialization:\n\nclass _ProductPage(GetAttr):\n def __init__(self, page, price): self.default,self.price = page,price #self.default allows you to access page directly.\n\np = _ProductPage(page, 15.0)\n\nNow, we can access the author attribute directly from the instance:\n\ntest_eq(p.author, 'Sylvain')\n\nIf you wish to store the object you are composing in an attribute other than self.default, you can set the class attribute _data as shown below. This is useful in the case where you might have a name collision with self.default:\n\nclass _C(GetAttr):\n _default = '_data' # use different component name; `self._data` rather than `self.default`\n def __init__(self,a): self._data = a\n def foo(self): noop\n\nt = _C('Hi')\ntest_eq(t._data, 'Hi') \ntest_fail(lambda: t.default) # we no longer have self.default\ntest_eq(t.lower(), 'hi')\ntest_eq(t.upper(), 'HI')\nassert 'lower' in dir(t)\nassert 'upper' in dir(t)\n\nBy default, all attributes and methods of the object you are composing are retained. In the below example, we compose a str object with the class _C. This allows us to directly call string methods on instances of class _C, such as str.lower() or str.upper():\n\nclass _C(GetAttr):\n # allow all attributes and methods to get passed to `self.default` (by leaving _xtra=None)\n def __init__(self,a): self.default = a\n def foo(self): noop\n\nt = _C('Hi')\ntest_eq(t.lower(), 'hi')\ntest_eq(t.upper(), 'HI')\nassert 'lower' in dir(t)\nassert 'upper' in dir(t)\n\nHowever, you can choose which attributes or methods to retain by defining a class attribute _xtra, which is a list of allowed attribute and method names to delegate. In the below example, we only delegate the lower method from the composed str object when defining class _C:\n\nclass _C(GetAttr):\n _xtra = ['lower'] # specify which attributes get passed to `self.default`\n def __init__(self,a): self.default = a\n def foo(self): noop\n\nt = _C('Hi')\ntest_eq(t.default, 'Hi')\ntest_eq(t.lower(), 'hi')\ntest_fail(lambda: t.upper()) # upper wasn't in _xtra, so it isn't available to be called\nassert 'lower' in dir(t)\nassert 'upper' not in dir(t)\n\nYou must be careful to properly set an instance attribute in __init__ that corresponds to the class attribute _default. The below example sets the class attribute _default to data, but erroneously fails to define self.data (and instead defines self.default).\nFailing to properly set instance attributes leads to errors when you try to access methods directly:\n\nclass _C(GetAttr):\n _default = 'data' # use a bad component name; i.e. self.data does not exist\n def __init__(self,a): self.default = a\n def foo(self): noop\n \n# TODO: should we raise an error when we create a new instance ...\nt = _C('Hi')\ntest_eq(t.default, 'Hi')\n# ... or is it enough for all GetAttr features to raise errors\ntest_fail(lambda: t.data)\ntest_fail(lambda: t.lower())\ntest_fail(lambda: t.upper())\ntest_fail(lambda: dir(t))\n\n\nsource\n\n\n\ndelegate_attr\n\n delegate_attr (k, to)\n\nUse in __getattr__ to delegate to attr to without inheriting from GetAttr\ndelegate_attr is a functional way to delegate attributes, and is an alternative to GetAttr. We recommend reading the documentation of GetAttr for more details around delegation.\nYou can use achieve delegation when you define __getattr__ by using delegate_attr:\n\nclass _C:\n def __init__(self, o): self.o = o # self.o corresponds to the `to` argument in delegate_attr.\n def __getattr__(self, k): return delegate_attr(self, k, to='o')\n \n\nt = _C('HELLO') # delegates to a string\ntest_eq(t.lower(), 'hello')\n\nt = _C(np.array([5,4,3])) # delegates to a numpy array\ntest_eq(t.sum(), 12)\n\nt = _C(pd.DataFrame({'a': [1,2], 'b': [3,4]})) # delegates to a pandas.DataFrame\ntest_eq(t.b.max(), 4)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#extensible-types", + "href": "basics.html#extensible-types", + "title": "Basic functionality", + "section": "Extensible Types", + "text": "Extensible Types\nShowPrint is a base class that defines a show method, which is used primarily for callbacks in fastai that expect this method to be defined.\nInt, Float, and Str extend int, float and str respectively by adding an additional show method by inheriting from ShowPrint.\nThe code for Int is shown below:\nExamples:\n\nInt(0).show()\nFloat(2.0).show()\nStr('Hello').show()\n\n0\n2.0\nHello", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#collection-functions", + "href": "basics.html#collection-functions", + "title": "Basic functionality", + "section": "Collection functions", + "text": "Collection functions\nFunctions that manipulate popular python collections.\n\nsource\n\npartition\n\n partition (coll, f)\n\nPartition a collection by a predicate\n\nts,fs = partition(range(10), mod(2))\ntest_eq(fs, [0,2,4,6,8])\ntest_eq(ts, [1,3,5,7,9])\n\n\nsource\n\n\nflatten\n\n flatten (o)\n\nConcatenate all collections and items as a generator\n\nsource\n\n\nconcat\n\n concat (colls)\n\nConcatenate all collections and items as a list\n\nconcat([(o for o in range(2)),[2,3,4], 5])\n\n[0, 1, 2, 3, 4, 5]\n\n\n\nconcat([[\"abc\", \"xyz\"], [\"foo\", \"bar\"]])\n\n['abc', 'xyz', 'foo', 'bar']\n\n\n\nsource\n\n\nstrcat\n\n strcat (its, sep:str='')\n\nConcatenate stringified items its\n\ntest_eq(strcat(['a',2]), 'a2')\ntest_eq(strcat(['a',2], ';'), 'a;2')\n\n\nsource\n\n\ndetuplify\n\n detuplify (x)\n\nIf x is a tuple with one thing, extract it\n\ntest_eq(detuplify(()),None)\ntest_eq(detuplify([1]),1)\ntest_eq(detuplify([1,2]), [1,2])\ntest_eq(detuplify(np.array([[1,2]])), np.array([[1,2]]))\n\n\nsource\n\n\nreplicate\n\n replicate (item, match)\n\nCreate tuple of item copied len(match) times\n\nt = [1,1]\ntest_eq(replicate([1,2], t),([1,2],[1,2]))\ntest_eq(replicate(1, t),(1,1))\n\n\nsource\n\n\nsetify\n\n setify (o)\n\nTurn any list like-object into a set.\n\n# test\ntest_eq(setify(None),set())\ntest_eq(setify('abc'),{'abc'})\ntest_eq(setify([1,2,2]),{1,2})\ntest_eq(setify(range(0,3)),{0,1,2})\ntest_eq(setify({1,2}),{1,2})\n\n\nsource\n\n\nmerge\n\n merge (*ds)\n\nMerge all dictionaries in ds\n\ntest_eq(merge(), {})\ntest_eq(merge(dict(a=1,b=2)), dict(a=1,b=2))\ntest_eq(merge(dict(a=1,b=2), dict(b=3,c=4), None), dict(a=1, b=3, c=4))\n\n\nsource\n\n\nrange_of\n\n range_of (x)\n\nAll indices of collection x (i.e. list(range(len(x))))\n\ntest_eq(range_of([1,1,1,1]), [0,1,2,3])\n\n\nsource\n\n\ngroupby\n\n groupby (x, key, val=<function noop>)\n\nLike itertools.groupby but doesn’t need to be sorted, and isn’t lazy, plus some extensions\n\ntest_eq(groupby('aa ab bb'.split(), itemgetter(0)), {'a':['aa','ab'], 'b':['bb']})\n\nHere’s an example of how to invert a grouping, using an int as key (which uses itemgetter; passing a str will use attrgetter), and using a val function:\n\nd = {0: [1, 3, 7], 2: [3], 3: [5], 4: [8], 5: [4], 7: [5]}\ngroupby(((o,k) for k,v in d.items() for o in v), 0, 1)\n\n{1: [0], 3: [0, 2], 7: [0], 5: [3, 7], 8: [4], 4: [5]}\n\n\n\nsource\n\n\nlast_index\n\n last_index (x, o)\n\nFinds the last index of occurence of x in o (returns -1 if no occurence)\n\ntest_eq(last_index(9, [1, 2, 9, 3, 4, 9, 10]), 5)\ntest_eq(last_index(6, [1, 2, 9, 3, 4, 9, 10]), -1)\n\n\nsource\n\n\nfilter_dict\n\n filter_dict (d, func)\n\nFilter a dict using func, applied to keys and values\n\nletters = {o:chr(o) for o in range(65,73)}\nletters\n\n{65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H'}\n\n\n\nfilter_dict(letters, lambda k,v: k<67 or v in 'FG')\n\n{65: 'A', 66: 'B', 70: 'F', 71: 'G'}\n\n\n\nsource\n\n\nfilter_keys\n\n filter_keys (d, func)\n\nFilter a dict using func, applied to keys\n\nfilter_keys(letters, lt(67))\n\n{65: 'A', 66: 'B'}\n\n\n\nsource\n\n\nfilter_values\n\n filter_values (d, func)\n\nFilter a dict using func, applied to values\n\nfilter_values(letters, in_('FG'))\n\n{70: 'F', 71: 'G'}\n\n\n\nsource\n\n\ncycle\n\n cycle (o)\n\nLike itertools.cycle except creates list of Nones if o is empty\n\ntest_eq(itertools.islice(cycle([1,2,3]),5), [1,2,3,1,2])\ntest_eq(itertools.islice(cycle([]),3), [None]*3)\ntest_eq(itertools.islice(cycle(None),3), [None]*3)\ntest_eq(itertools.islice(cycle(1),3), [1,1,1])\n\n\nsource\n\n\nzip_cycle\n\n zip_cycle (x, *args)\n\nLike itertools.zip_longest but cycles through elements of all but first argument\n\ntest_eq(zip_cycle([1,2,3,4],list('abc')), [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'a')])\n\n\nsource\n\n\nsorted_ex\n\n sorted_ex (iterable, key=None, reverse=False)\n\nLike sorted, but if key is str use attrgetter; if int use itemgetter\n\nsource\n\n\nnot_\n\n not_ (f)\n\nCreate new function that negates result of f\n\ndef f(a): return a>0\ntest_eq(f(1),True)\ntest_eq(not_(f)(1),False)\ntest_eq(not_(f)(a=-1),True)\n\n\nsource\n\n\nargwhere\n\n argwhere (iterable, f, negate=False, **kwargs)\n\nLike filter_ex, but return indices for matching items\n\nsource\n\n\nfilter_ex\n\n filter_ex (iterable, f=<function noop>, negate=False, gen=False,\n **kwargs)\n\nLike filter, but passing kwargs to f, defaulting f to noop, and adding negate and gen\n\nsource\n\n\nrange_of\n\n range_of (a, b=None, step=None)\n\nAll indices of collection a, if a is a collection, otherwise range\n\ntest_eq(range_of([1,1,1,1]), [0,1,2,3])\ntest_eq(range_of(4), [0,1,2,3])\n\n\nsource\n\n\nrenumerate\n\n renumerate (iterable, start=0)\n\nSame as enumerate, but returns index as 2nd element instead of 1st\n\ntest_eq(renumerate('abc'), (('a',0),('b',1),('c',2)))\n\n\nsource\n\n\nfirst\n\n first (x, f=None, negate=False, **kwargs)\n\nFirst element of x, optionally filtered by f, or None if missing\n\ntest_eq(first(['a', 'b', 'c', 'd', 'e']), 'a')\ntest_eq(first([False]), False)\ntest_eq(first([False], noop), None)\n\n\nsource\n\n\nonly\n\n only (o)\n\nReturn the only item of o, raise if o doesn’t have exactly one item\n\nsource\n\n\nnested_attr\n\n nested_attr (o, attr, default=None)\n\nSame as getattr, but if attr includes a ., then looks inside nested objects\n\na = SimpleNamespace(b=(SimpleNamespace(c=1)))\ntest_eq(nested_attr(a, 'b.c'), getattr(getattr(a, 'b'), 'c'))\ntest_eq(nested_attr(a, 'b.d'), None)\n\n\nsource\n\n\nnested_setdefault\n\n nested_setdefault (o, attr, default)\n\nSame as setdefault, but if attr includes a ., then looks inside nested objects\n\nsource\n\n\nnested_callable\n\n nested_callable (o, attr)\n\nSame as nested_attr but if not found will return noop\n\na = SimpleNamespace(b=(SimpleNamespace(c=1)))\ntest_eq(nested_callable(a, 'b.c'), getattr(getattr(a, 'b'), 'c'))\ntest_eq(nested_callable(a, 'b.d'), noop)\n\n\nsource\n\n\nnested_idx\n\n nested_idx (coll, *idxs)\n\nIndex into nested collections, dicts, etc, with idxs\n\na = {'b':[1,{'c':2}]}\ntest_eq(nested_idx(a, 'nope'), None)\ntest_eq(nested_idx(a, 'nope', 'nup'), None)\ntest_eq(nested_idx(a, 'b', 3), None)\ntest_eq(nested_idx(a), a)\ntest_eq(nested_idx(a, 'b'), [1,{'c':2}])\ntest_eq(nested_idx(a, 'b', 1), {'c':2})\ntest_eq(nested_idx(a, 'b', 1, 'c'), 2)\n\n\na = SimpleNamespace(b=[1,{'c':2}])\ntest_eq(nested_idx(a, 'nope'), None)\ntest_eq(nested_idx(a, 'nope', 'nup'), None)\ntest_eq(nested_idx(a, 'b', 3), None)\ntest_eq(nested_idx(a), a)\ntest_eq(nested_idx(a, 'b'), [1,{'c':2}])\ntest_eq(nested_idx(a, 'b', 1), {'c':2})\ntest_eq(nested_idx(a, 'b', 1, 'c'), 2)\n\n\nsource\n\n\nset_nested_idx\n\n set_nested_idx (coll, value, *idxs)\n\nSet value indexed like `nested_idx\n\nset_nested_idx(a, 3, 'b', 0)\ntest_eq(nested_idx(a, 'b', 0), 3)\n\n\nsource\n\n\nval2idx\n\n val2idx (x)\n\nDict from value to index\n\ntest_eq(val2idx([1,2,3]), {3:2,1:0,2:1})\n\n\nsource\n\n\nuniqueify\n\n uniqueify (x, sort=False, bidir=False, start=None)\n\nUnique elements in x, optional sort, optional return reverse correspondence, optional prepend with elements.\n\nt = [1,1,0,5,0,3]\ntest_eq(uniqueify(t),[1,0,5,3])\ntest_eq(uniqueify(t, sort=True),[0,1,3,5])\ntest_eq(uniqueify(t, start=[7,8,6]), [7,8,6,1,0,5,3])\nv,o = uniqueify(t, bidir=True)\ntest_eq(v,[1,0,5,3])\ntest_eq(o,{1:0, 0: 1, 5: 2, 3: 3})\nv,o = uniqueify(t, sort=True, bidir=True)\ntest_eq(v,[0,1,3,5])\ntest_eq(o,{0:0, 1: 1, 3: 2, 5: 3})\n\n\nsource\n\n\nloop_first_last\n\n loop_first_last (values)\n\nIterate and generate a tuple with a flag for first and last value.\n\ntest_eq(loop_first_last(range(3)), [(True,False,0), (False,False,1), (False,True,2)])\n\n\nsource\n\n\nloop_first\n\n loop_first (values)\n\nIterate and generate a tuple with a flag for first value.\n\ntest_eq(loop_first(range(3)), [(True,0), (False,1), (False,2)])\n\n\nsource\n\n\nloop_last\n\n loop_last (values)\n\nIterate and generate a tuple with a flag for last value.\n\ntest_eq(loop_last(range(3)), [(False,0), (False,1), (True,2)])\n\n\nsource\n\n\nfirst_match\n\n first_match (lst, f, default=None)\n\nFirst element of lst matching predicate f, or default if none\n\na = [0,2,4,5,6,7,10]\ntest_eq(first_match(a, lambda o:o%2), 3)\n\n\nsource\n\n\nlast_match\n\n last_match (lst, f, default=None)\n\nLast element of lst matching predicate f, or default if none\n\ntest_eq(last_match(a, lambda o:o%2), 5)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#fastuple", + "href": "basics.html#fastuple", + "title": "Basic functionality", + "section": "fastuple", + "text": "fastuple\nA tuple with extended functionality.\n\nsource\n\nfastuple\n\n fastuple (x=None, *rest)\n\nA tuple with elementwise ops and more friendly init behavior\n\n\nFriendly init behavior\nCommon failure modes when trying to initialize a tuple in python:\ntuple(3)\n> TypeError: 'int' object is not iterable\nor\ntuple(3, 4)\n> TypeError: tuple expected at most 1 arguments, got 2\nHowever, fastuple allows you to define tuples like this and in the usual way:\n\ntest_eq(fastuple(3), (3,))\ntest_eq(fastuple(3,4), (3, 4))\ntest_eq(fastuple((3,4)), (3, 4))\n\n\n\nElementwise operations\n\nsource\n\nfastuple.add\n\n fastuple.add (*args)\n\n+ is already defined in tuple for concat, so use add instead\n\ntest_eq(fastuple.add((1,1),(2,2)), (3,3))\ntest_eq_type(fastuple(1,1).add(2), fastuple(3,3))\ntest_eq(fastuple('1','2').add('2'), fastuple('12','22'))\n\n\nsource\n\n\nfastuple.mul\n\n fastuple.mul (*args)\n\n* is already defined in tuple for replicating, so use mul instead\n\ntest_eq_type(fastuple(1,1).mul(2), fastuple(2,2))\n\n\n\n\nOther Elementwise Operations\nAdditionally, the following elementwise operations are available: - le: less than or equal - eq: equal - gt: greater than - min: minimum of\n\ntest_eq(fastuple(3,1).le(1), (False, True))\ntest_eq(fastuple(3,1).eq(1), (False, True))\ntest_eq(fastuple(3,1).gt(1), (True, False))\ntest_eq(fastuple(3,1).min(2), (2,1))\n\nYou can also do other elementwise operations like negate a fastuple, or subtract two fastuples:\n\ntest_eq(-fastuple(1,2), (-1,-2))\ntest_eq(~fastuple(1,0,1), (False,True,False))\n\ntest_eq(fastuple(1,1)-fastuple(2,2), (-1,-1))\n\n\ntest_eq(type(fastuple(1)), fastuple)\ntest_eq_type(fastuple(1,2), fastuple(1,2))\ntest_ne(fastuple(1,2), fastuple(1,3))\ntest_eq(fastuple(), ())", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#functions-on-functions", + "href": "basics.html#functions-on-functions", + "title": "Basic functionality", + "section": "Functions on Functions", + "text": "Functions on Functions\nUtilities for functional programming or for defining, modifying, or debugging functions.\n\nsource\n\nbind\n\n bind (func, *pargs, **pkwargs)\n\nSame as partial, except you can use arg0 arg1 etc param placeholders\nbind is the same as partial, but also allows you to reorder positional arguments using variable name(s) arg{i} where i refers to the zero-indexed positional argument. bind as implemented currently only supports reordering of up to the first 5 positional arguments.\nConsider the function myfunc below, which has 3 positional arguments. These arguments can be referenced as arg0, arg1, and arg1, respectively.\n\ndef myfn(a,b,c,d=1,e=2): return(a,b,c,d,e)\n\nIn the below example we bind the positional arguments of myfn as follows:\n\nThe second input 14, referenced by arg1, is substituted for the first positional argument.\nWe supply a default value of 17 for the second positional argument.\nThe first input 19, referenced by arg0, is subsituted for the third positional argument.\n\n\ntest_eq(bind(myfn, arg1, 17, arg0, e=3)(19,14), (14,17,19,1,3))\n\nIn this next example:\n\nWe set the default value to 17 for the first positional argument.\nThe first input 19 refrenced by arg0, becomes the second positional argument.\nThe second input 14 becomes the third positional argument.\nWe override the default the value for named argument e to 3.\n\n\ntest_eq(bind(myfn, 17, arg0, e=3)(19,14), (17,19,14,1,3))\n\nThis is an example of using bind like partial and do not reorder any arguments:\n\ntest_eq(bind(myfn)(17,19,14), (17,19,14,1,2))\n\nbind can also be used to change default values. In the below example, we use the first input 3 to override the default value of the named argument e, and supply default values for the first three positional arguments:\n\ntest_eq(bind(myfn, 17,19,14,e=arg0)(3), (17,19,14,1,3))\n\n\nsource\n\n\nmapt\n\n mapt (func, *iterables)\n\nTuplified map\n\nt = [0,1,2,3]\ntest_eq(mapt(operator.neg, t), (0,-1,-2,-3))\n\n\nsource\n\n\nmap_ex\n\n map_ex (iterable, f, *args, gen=False, **kwargs)\n\nLike map, but use bind, and supports str and indexing\n\ntest_eq(map_ex(t,operator.neg), [0,-1,-2,-3])\n\nIf f is a string then it is treated as a format string to create the mapping:\n\ntest_eq(map_ex(t, '#{}#'), ['#0#','#1#','#2#','#3#'])\n\nIf f is a dictionary (or anything supporting __getitem__) then it is indexed to create the mapping:\n\ntest_eq(map_ex(t, list('abcd')), list('abcd'))\n\nYou can also pass the same arg params that bind accepts:\n\ndef f(a=None,b=None): return b\ntest_eq(map_ex(t, f, b=arg0), range(4))\n\n\nsource\n\n\ncompose\n\n compose (*funcs, order=None)\n\nCreate a function that composes all functions in funcs, passing along remaining *args and **kwargs to all\n\nf1 = lambda o,p=0: (o*2)+p\nf2 = lambda o,p=1: (o+1)/p\ntest_eq(f2(f1(3)), compose(f1,f2)(3))\ntest_eq(f2(f1(3,p=3),p=3), compose(f1,f2)(3,p=3))\ntest_eq(f2(f1(3, 3), 3), compose(f1,f2)(3, 3))\n\nf1.order = 1\ntest_eq(f1(f2(3)), compose(f1,f2, order=\"order\")(3))\n\n\nsource\n\n\nmaps\n\n maps (*args, retain=<function noop>)\n\nLike map, except funcs are composed first\n\ntest_eq(maps([1]), [1])\ntest_eq(maps(operator.neg, [1,2]), [-1,-2])\ntest_eq(maps(operator.neg, operator.neg, [1,2]), [1,2])\n\n\nsource\n\n\npartialler\n\n partialler (f, *args, order=None, **kwargs)\n\nLike functools.partial but also copies over docstring\n\ndef _f(x,a=1):\n \"test func\"\n return x-a\n_f.order=1\n\nf = partialler(_f, 2)\ntest_eq(f.order, 1)\ntest_eq(f(3), -1)\nf = partialler(_f, a=2, order=3)\ntest_eq(f.__doc__, \"test func\")\ntest_eq(f.order, 3)\ntest_eq(f(3), _f(3,2))\n\n\nclass partial0:\n \"Like `partialler`, but args passed to callable are inserted at started, instead of at end\"\n def __init__(self, f, *args, order=None, **kwargs):\n self.f,self.args,self.kwargs = f,args,kwargs\n self.order = ifnone(order, getattr(f,'order',None))\n self.__doc__ = f.__doc__\n\n def __call__(self, *args, **kwargs): return self.f(*args, *self.args, **kwargs, **self.kwargs)\n\n\nf = partial0(_f, 2)\ntest_eq(f.order, 1)\ntest_eq(f(3), 1) # NB: different to `partialler` example\n\n\nsource\n\n\ninstantiate\n\n instantiate (t)\n\nInstantiate t if it’s a type, otherwise do nothing\n\ntest_eq_type(instantiate(int), 0)\ntest_eq_type(instantiate(1), 1)\n\n\nsource\n\n\nusing_attr\n\n using_attr (f, attr)\n\nConstruct a function which applies f to the argument’s attribute attr\n\nt = Path('/a/b.txt')\nf = using_attr(str.upper, 'name')\ntest_eq(f(t), 'B.TXT')\n\n\n\nSelf (with an uppercase S)\nA Concise Way To Create Lambdas\nThis is a concise way to create lambdas that are calling methods on an object (note the capitalization!)\nSelf.sum(), for instance, is a shortcut for lambda o: o.sum().\n\nf = Self.sum()\nx = np.array([3.,1])\ntest_eq(f(x), 4.)\n\n# This is equivalent to above\nf = lambda o: o.sum()\nx = np.array([3.,1])\ntest_eq(f(x), 4.)\n\nf = Self.argmin()\narr = np.array([1,2,3,4,5])\ntest_eq(f(arr), arr.argmin())\n\nf = Self.sum().is_integer()\nx = np.array([3.,1])\ntest_eq(f(x), True)\n\nf = Self.sum().real.is_integer()\nx = np.array([3.,1])\ntest_eq(f(x), True)\n\nf = Self.imag()\ntest_eq(f(3), 0)\n\nf = Self[1]\ntest_eq(f(x), 1)\n\nSelf is also callable, which creates a function which calls any function passed to it, using the arguments passed to Self:\n\ndef f(a, b=3): return a+b+2\ndef g(a, b=3): return a*b\nfg = Self(1,b=2)\nlist(map(fg, [f,g]))\n\n[5, 2]", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#patching", + "href": "basics.html#patching", + "title": "Basic functionality", + "section": "Patching", + "text": "Patching\n\nsource\n\ncopy_func\n\n copy_func (f)\n\nCopy a non-builtin function (NB copy.copy does not work for this)\nSometimes it may be desirable to make a copy of a function that doesn’t point to the original object. When you use Python’s built in copy.copy or copy.deepcopy to copy a function, you get a reference to the original object:\n\nimport copy as cp\n\n\ndef foo(): pass\na = cp.copy(foo)\nb = cp.deepcopy(foo)\n\na.someattr = 'hello' # since a and b point at the same object, updating a will update b\ntest_eq(b.someattr, 'hello')\n\nassert a is foo and b is foo\n\nHowever, with copy_func, you can retrieve a copy of a function without a reference to the original object:\n\nc = copy_func(foo) # c is an indpendent object\nassert c is not foo\n\n\ndef g(x, *, y=3): return x+y\ntest_eq(copy_func(g)(4), 7)\n\n\nsource\n\n\npatch_to\n\n patch_to (cls, as_prop=False, cls_method=False)\n\nDecorator: add f to cls\nThe @patch_to decorator allows you to monkey patch a function into a class as a method:\n\nclass _T3(int): pass \n\n@patch_to(_T3)\ndef func1(self, a): return self+a\n\nt = _T3(1) # we initialized `t` to a type int = 1\ntest_eq(t.func1(2), 3) # we add 2 to `t`, so 2 + 1 = 3\n\nYou can access instance properties in the usual way via self:\n\nclass _T4():\n def __init__(self, g): self.g = g\n \n@patch_to(_T4)\ndef greet(self, x): return self.g + x\n \nt = _T4('hello ') # this sets self.g = 'hello '\ntest_eq(t.greet('world'), 'hello world') #t.greet('world') will append 'world' to 'hello '\n\nYou can instead specify that the method should be a class method by setting cls_method=True:\n\nclass _T5(int): attr = 3 # attr is a class attribute we will access in a later method\n \n@patch_to(_T5, cls_method=True)\ndef func(cls, x): return cls.attr + x # you can access class attributes in the normal way\n\ntest_eq(_T5.func(4), 7)\n\nAdditionally you can specify that the function you want to patch should be a class attribute with as_prop=True:\n\n@patch_to(_T5, as_prop=True)\ndef add_ten(self): return self + 10\n\nt = _T5(4)\ntest_eq(t.add_ten, 14)\n\nInstead of passing one class to the @patch_to decorator, you can pass multiple classes in a tuple to simulteanously patch more than one class with the same method:\n\nclass _T6(int): pass\nclass _T7(int): pass\n\n@patch_to((_T6,_T7))\ndef func_mult(self, a): return self*a\n\nt = _T6(2)\ntest_eq(t.func_mult(4), 8)\nt = _T7(2)\ntest_eq(t.func_mult(4), 8)\n\n\nsource\n\n\npatch\n\n patch (f=None, as_prop=False, cls_method=False)\n\nDecorator: add f to the first parameter’s class (based on f’s type annotations)\n@patch is an alternative to @patch_to that allows you similarly monkey patch class(es) by using type annotations:\n\nclass _T8(int): pass \n\n@patch\ndef func(self:_T8, a): return self+a\n\nt = _T8(1) # we initilized `t` to a type int = 1\ntest_eq(t.func(3), 4) # we add 3 to `t`, so 3 + 1 = 4\ntest_eq(t.func.__qualname__, '_T8.func')\n\nSimilarly to patch_to, you can supply a union of classes instead of a single class in your type annotations to patch multiple classes:\n\nclass _T9(int): pass \n\n@patch\ndef func2(x:_T8|_T9, a): return x*a # will patch both _T8 and _T9\n\nt = _T8(2)\ntest_eq(t.func2(4), 8)\ntest_eq(t.func2.__qualname__, '_T8.func2')\n\nt = _T9(2)\ntest_eq(t.func2(4), 8)\ntest_eq(t.func2.__qualname__, '_T9.func2')\n\nJust like patch_to decorator you can use as_prop and cls_method parameters with patch decorator:\n\n@patch(as_prop=True)\ndef add_ten(self:_T5): return self + 10\n\nt = _T5(4)\ntest_eq(t.add_ten, 14)\n\n\nclass _T5(int): attr = 3 # attr is a class attribute we will access in a later method\n \n@patch(cls_method=True)\ndef func(cls:_T5, x): return cls.attr + x # you can access class attributes in the normal way\n\ntest_eq(_T5.func(4), 7)\n\n\nsource\n\n\npatch_property\n\n patch_property (f)\n\nDeprecated; use patch(as_prop=True) instead\nPatching classmethod shouldn’t affect how python’s inheritance works\n\nclass FastParent: pass\n\n@patch(cls_method=True)\ndef type_cls(cls: FastParent): return cls\n\nclass FastChild(FastParent): pass\n\nparent = FastParent()\ntest_eq(parent.type_cls(), FastParent)\n\nchild = FastChild()\ntest_eq(child.type_cls(), FastChild)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#other-helpers", + "href": "basics.html#other-helpers", + "title": "Basic functionality", + "section": "Other Helpers", + "text": "Other Helpers\n\nsource\n\ncompile_re\n\n compile_re (pat)\n\nCompile pat if it’s not None\n\nassert compile_re(None) is None\nassert compile_re('a').match('ab')\n\n\nsource\n\nImportEnum\n\n ImportEnum (value, names=None, module=None, qualname=None, type=None,\n start=1)\n\nAn Enum that can have its values imported\n\n_T = ImportEnum('_T', {'foobar':1, 'goobar':2})\n_T.imports()\ntest_eq(foobar, _T.foobar)\ntest_eq(goobar, _T.goobar)\n\n\nsource\n\n\nStrEnum\n\n StrEnum (value, names=None, module=None, qualname=None, type=None,\n start=1)\n\nAn ImportEnum that behaves like a str\n\nsource\n\n\n\nstr_enum\n\n str_enum (name, *vals)\n\nSimplified creation of StrEnum types\n\nsource\n\nValEnum\n\n ValEnum (value, names=None, module=None, qualname=None, type=None,\n start=1)\n\nAn ImportEnum that stringifies using values\n\n_T = str_enum('_T', 'a', 'b')\ntest_eq(f'{_T.a}', 'a')\ntest_eq(_T.a, 'a')\ntest_eq(list(_T.__members__), ['a','b'])\nprint(_T.a, _T.a.upper())\n\na A\n\n\n\nsource\n\n\nStateful\n\n Stateful (*args, **kwargs)\n\nA base class/mixin for objects that should not serialize all their state\n\nclass _T(Stateful):\n def __init__(self):\n super().__init__()\n self.a=1\n self._state['test']=2\n\nt = _T()\nt2 = pickle.loads(pickle.dumps(t))\ntest_eq(t.a,1)\ntest_eq(t._state['test'],2)\ntest_eq(t2.a,1)\ntest_eq(t2._state,{})\n\nOverride _init_state to do any necessary setup steps that are required during __init__ or during deserialization (e.g. pickle.load). Here’s an example of how Stateful simplifies the official Python example for Handling Stateful Objects.\n\nclass TextReader(Stateful):\n \"\"\"Print and number lines in a text file.\"\"\"\n _stateattrs=('file',)\n def __init__(self, filename):\n self.filename,self.lineno = filename,0\n super().__init__()\n\n def readline(self):\n self.lineno += 1\n line = self.file.readline()\n if line: return f\"{self.lineno}: {line.strip()}\"\n\n def _init_state(self):\n self.file = open(self.filename)\n for _ in range(self.lineno): self.file.readline()\n\n\nreader = TextReader(\"00_test.ipynb\")\nprint(reader.readline())\nprint(reader.readline())\n\nnew_reader = pickle.loads(pickle.dumps(reader))\nprint(reader.readline())\n\n1: {\n2: \"cells\": [\n3: {\n\n\n\nsource\n\n\n\nNotStr\n\n NotStr (s)\n\nBehaves like a str, but isn’t an instance of one\n\ns = NotStr(\"hello\")\nassert not isinstance(s, str)\ntest_eq(s, 'hello')\ntest_eq(s*2, 'hellohello')\ntest_eq(len(s), 5)\n\n\nsource\n\nPrettyString\nLittle hack to get strings to show properly in Jupyter.\nAllow strings with special characters to render properly in Jupyter. Without calling print() strings with special characters are displayed like so:\n\nwith_special_chars='a string\\nwith\\nnew\\nlines and\\ttabs'\nwith_special_chars\n\n'a string\\nwith\\nnew\\nlines and\\ttabs'\n\n\nWe can correct this with PrettyString:\n\nPrettyString(with_special_chars)\n\na string\nwith\nnew\nlines and tabs\n\n\n\nsource\n\n\n\neven_mults\n\n even_mults (start, stop, n)\n\nBuild log-stepped array from start to stop in n steps.\n\ntest_eq(even_mults(2,8,3), [2,4,8])\ntest_eq(even_mults(2,32,5), [2,4,8,16,32])\ntest_eq(even_mults(2,8,1), 8)\n\n\nsource\n\n\nnum_cpus\n\n num_cpus ()\n\nGet number of cpus\n\nnum_cpus()\n\n8\n\n\n\nsource\n\n\nadd_props\n\n add_props (f, g=None, n=2)\n\nCreate properties passing each of range(n) to f\n\nclass _T(): a,b = add_props(lambda i,x:i*2)\n\nt = _T()\ntest_eq(t.a,0)\ntest_eq(t.b,2)\n\n\nclass _T(): \n def __init__(self, v): self.v=v\n def _set(i, self, v): self.v[i] = v\n a,b = add_props(lambda i,x: x.v[i], _set)\n\nt = _T([0,2])\ntest_eq(t.a,0)\ntest_eq(t.b,2)\nt.a = t.a+1\nt.b = 3\ntest_eq(t.a,1)\ntest_eq(t.b,3)\n\n\nsource\n\n\ntyped\n\n typed (f)\n\nDecorator to check param and return types at runtime\ntyped validates argument types at runtime. This is in contrast to MyPy which only offers static type checking.\nFor example, a TypeError will be raised if we try to pass an integer into the first argument of the below function:\n\n@typed\ndef discount(price:int, pct:float): \n return (1-pct) * price\n\nwith ExceptionExpected(TypeError): discount(100.0, .1)\n\nWe can also optionally allow multiple types by enumarating the types in a tuple as illustrated below:\n\ndef discount(price:int|float, pct:float): \n return (1-pct) * price\n\nassert 90.0 == discount(100.0, .1)\n\n\n@typed\ndef foo(a:int, b:str='a'): return a\ntest_eq(foo(1, '2'), 1)\n\nwith ExceptionExpected(TypeError): foo(1,2)\n\n@typed\ndef foo()->str: return 1\nwith ExceptionExpected(TypeError): foo()\n\n@typed\ndef foo()->str: return '1'\nassert foo()\n\ntyped works with classes, too:\n\nclass Foo:\n @typed\n def __init__(self, a:int, b: int, c:str): pass\n @typed\n def test(cls, d:str): return d\n\nwith ExceptionExpected(TypeError): Foo(1, 2, 3) \nwith ExceptionExpected(TypeError): Foo(1,2, 'a string').test(10)\n\n\nsource\n\n\nexec_new\n\n exec_new (code)\n\nExecute code in a new environment and return it\n\ng = exec_new('a=1')\ntest_eq(g['a'], 1)\n\n\nsource\n\n\nexec_import\n\n exec_import (mod, sym)\n\nImport sym from mod in a new environment\n\nsource\n\n\nstr2bool\n\n str2bool (s)\n\nCase-insensitive convert string s too a bool (y,yes,t,true,on,1->True)\nTrue values are ‘y’, ‘yes’, ‘t’, ‘true’, ‘on’, and ‘1’; false values are ‘n’, ‘no’, ‘f’, ‘false’, ‘off’, and ‘0’. Raises ValueError if ‘val’ is anything else.\n\nfor o in \"y YES t True on 1\".split(): assert str2bool(o)\nfor o in \"n no FALSE off 0\".split(): assert not str2bool(o)\nfor o in 0,None,'',False: assert not str2bool(o)\nfor o in 1,True: assert str2bool(o)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "basics.html#notebook-functions", + "href": "basics.html#notebook-functions", + "title": "Basic functionality", + "section": "Notebook functions", + "text": "Notebook functions\n\n\nipython_shell\n\n ipython_shell ()\n\nSame as get_ipython but returns False if not in IPython\n\n\n\nin_ipython\n\n in_ipython ()\n\nCheck if code is running in some kind of IPython environment\n\n\n\nin_colab\n\n in_colab ()\n\nCheck if the code is running in Google Colaboratory\n\n\n\nin_jupyter\n\n in_jupyter ()\n\nCheck if the code is running in a jupyter notebook\n\n\n\nin_notebook\n\n in_notebook ()\n\nCheck if the code is running in a jupyter notebook\nThese variables are available as booleans in fastcore.basics as IN_IPYTHON, IN_JUPYTER, IN_COLAB and IN_NOTEBOOK.\n\nIN_IPYTHON, IN_JUPYTER, IN_COLAB, IN_NOTEBOOK\n\n(True, True, False, True)", + "crumbs": [ + "Basic functionality" + ] + }, + { + "objectID": "xtras.html", + "href": "xtras.html", + "title": "Utility functions", + "section": "", + "text": "Utilities (other than extensions to Pathlib.Path) for dealing with IO.\n\nsource\n\n\n\n walk (path:pathlib.Path|str, symlinks:bool=True, keep_file:<built-\n infunctioncallable>=<function ret_true>, keep_folder:<built-\n infunctioncallable>=<function ret_true>, skip_folder:<built-\n infunctioncallable>=<function ret_false>, func:<built-\n infunctioncallable>=<function join>, ret_folders:bool=False)\n\nGenerator version of os.walk, using functions to filter files and folders\n\n\n\n\n\n\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\npath\nPath | str\n\npath to start searching\n\n\nsymlinks\nbool\nTrue\nfollow symlinks?\n\n\nkeep_file\ncallable\nret_true\nfunction that returns True for wanted files\n\n\nkeep_folder\ncallable\nret_true\nfunction that returns True for folders to enter\n\n\nskip_folder\ncallable\nret_false\nfunction that returns True for folders to skip\n\n\nfunc\ncallable\njoin\nfunction to apply to each matched file\n\n\nret_folders\nbool\nFalse\nreturn folders, not just files\n\n\n\n\nsource\n\n\n\n\n globtastic (path:pathlib.Path|str, recursive:bool=True,\n symlinks:bool=True, file_glob:str=None, file_re:str=None,\n folder_re:str=None, skip_file_glob:str=None,\n skip_file_re:str=None, skip_folder_re:str=None, func:<built-\n infunctioncallable>=<function join>, ret_folders:bool=False)\n\nA more powerful glob, including regex matches, symlink handling, and skip parameters\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\npath\nPath | str\n\npath to start searching\n\n\nrecursive\nbool\nTrue\nsearch subfolders\n\n\nsymlinks\nbool\nTrue\nfollow symlinks?\n\n\nfile_glob\nstr\nNone\nOnly include files matching glob\n\n\nfile_re\nstr\nNone\nOnly include files matching regex\n\n\nfolder_re\nstr\nNone\nOnly enter folders matching regex\n\n\nskip_file_glob\nstr\nNone\nSkip files matching glob\n\n\nskip_file_re\nstr\nNone\nSkip files matching regex\n\n\nskip_folder_re\nstr\nNone\nSkip folders matching regex,\n\n\nfunc\ncallable\njoin\nfunction to apply to each matched file\n\n\nret_folders\nbool\nFalse\nreturn folders, not just files\n\n\nReturns\nL\n\nPaths to matched files\n\n\n\n\nglobtastic('.', skip_folder_re='^[_.]', folder_re='core', file_glob='*.*py*', file_re='c')\n\n(#5) ['./fastcore/docments.py','./fastcore/dispatch.py','./fastcore/basics.py','./fastcore/docscrape.py','./fastcore/script.py']\n\n\n\nsource\n\n\n\n\n maybe_open (f, mode='r', **kwargs)\n\nContext manager: open f if it is a path (and close on exit)\nThis is useful for functions where you want to accept a path or file. maybe_open will not close your file handle if you pass one in.\n\ndef _f(fn):\n with maybe_open(fn) as f: return f.encoding\n\nfname = '00_test.ipynb'\nsys_encoding = 'cp1252' if sys.platform == 'win32' else 'UTF-8'\ntest_eq(_f(fname), sys_encoding)\nwith open(fname) as fh: test_eq(_f(fh), sys_encoding)\n\nFor example, we can use this to reimplement imghdr.what from the Python standard library, which is written in Python 3.9 as:\n\nfrom fastcore import imghdr\n\n\ndef what(file, h=None):\n f = None\n try:\n if h is None:\n if isinstance(file, (str,os.PathLike)):\n f = open(file, 'rb')\n h = f.read(32)\n else:\n location = file.tell()\n h = file.read(32)\n file.seek(location)\n for tf in imghdr.tests:\n res = tf(h, f)\n if res: return res\n finally:\n if f: f.close()\n return None\n\nHere’s an example of the use of this function:\n\nfname = 'images/puppy.jpg'\nwhat(fname)\n\n'jpeg'\n\n\nWith maybe_open, Self, and L.map_first, we can rewrite this in a much more concise and (in our opinion) clear way:\n\ndef what(file, h=None):\n if h is None:\n with maybe_open(file, 'rb') as f: h = f.peek(32)\n return L(imghdr.tests).map_first(Self(h,file))\n\n…and we can check that it still works:\n\ntest_eq(what(fname), 'jpeg')\n\n…along with the version passing a file handle:\n\nwith open(fname,'rb') as f: test_eq(what(f), 'jpeg')\n\n…along with the h parameter version:\n\nwith open(fname,'rb') as f: test_eq(what(None, h=f.read(32)), 'jpeg')\n\n\nsource\n\n\n\n\n mkdir (path, exist_ok=False, parents=False, overwrite=False, **kwargs)\n\nCreates and returns a directory defined by path, optionally removing previous existing directory if overwrite is True\n\nwith tempfile.TemporaryDirectory() as d:\n path = Path(os.path.join(d, 'new_dir'))\n new_dir = mkdir(path)\n assert new_dir.exists()\n test_eq(new_dir, path)\n \n # test overwrite\n with open(new_dir/'test.txt', 'w') as f: f.writelines('test')\n test_eq(len(list(walk(new_dir))), 1) # assert file is present\n new_dir = mkdir(new_dir, overwrite=True)\n test_eq(len(list(walk(new_dir))), 0) # assert file was deleted\n\n\nsource\n\n\n\n\n image_size (fn)\n\nTuple of (w,h) for png, gif, or jpg; None otherwise\n\ntest_eq(image_size(fname), (1200,803))\n\n\nsource\n\n\n\n\n bunzip (fn)\n\nbunzip fn, raising exception if output already exists\n\nf = Path('files/test.txt')\nif f.exists(): f.unlink()\nbunzip('files/test.txt.bz2')\nt = f.open().readlines()\ntest_eq(len(t),1)\ntest_eq(t[0], 'test\\n')\nf.unlink()\n\n\nsource\n\n\n\n\n loads (s, **kw)\n\nSame as json.loads, but handles None\n\nsource\n\n\n\n\n loads_multi (s:str)\n\nGenerator of >=0 decoded json dicts, possibly with non-json ignored text at start and end\n\ntst = \"\"\"\n# ignored\n{ \"a\":1 }\nhello\n{\n\"b\":2\n}\n\"\"\"\n\ntest_eq(list(loads_multi(tst)), [{'a': 1}, {'b': 2}])\n\n\nsource\n\n\n\n\n dumps (obj, **kw)\n\nSame as json.dumps, but uses ujson if available\n\nsource\n\n\n\n\n untar_dir (fname, dest, rename=False, overwrite=False)\n\nuntar file into dest, creating a directory if the root contains more than one item\n\ndef test_untar(foldername, rename=False, **kwargs):\n with tempfile.TemporaryDirectory() as d:\n nm = os.path.join(d, 'a')\n shutil.make_archive(nm, 'gztar', **kwargs)\n with tempfile.TemporaryDirectory() as d2:\n d2 = Path(d2)\n untar_dir(nm+'.tar.gz', d2, rename=rename)\n test_eq(d2.ls(), [d2/foldername])\n\nIf the contents of fname contain just one file or directory, it is placed directly in dest:\n\n# using `base_dir` in `make_archive` results in `images` directory included in file names\ntest_untar('images', base_dir='images')\n\nIf rename then the directory created is named based on the archive, without extension:\n\ntest_untar('a', base_dir='images', rename=True)\n\nIf the contents of fname contain multiple files and directories, a new folder in dest is created with the same name as fname (but without extension):\n\n# using `root_dir` in `make_archive` results in `images` directory *not* included in file names\ntest_untar('a', root_dir='images')\n\n\nsource\n\n\n\n\n repo_details (url)\n\nTuple of owner,name from ssh or https git repo url\n\ntest_eq(repo_details('https://github.com/fastai/fastai.git'), ['fastai', 'fastai'])\ntest_eq(repo_details('git@github.com:fastai/nbdev.git\\n'), ['fastai', 'nbdev'])\n\n\nsource\n\n\n\n\n run (cmd, *rest, same_in_win=False, ignore_ex=False, as_bytes=False,\n stderr=False)\n\nPass cmd (splitting with shlex if string) to subprocess.run; return stdout; raise IOError if fails\nYou can pass a string (which will be split based on standard shell rules), a list, or pass args directly:\n\nrun('echo', same_in_win=True)\nrun('pip', '--version', same_in_win=True)\nrun(['pip', '--version'], same_in_win=True)\n\n'pip 23.3.1 from /Users/jhoward/miniconda3/lib/python3.11/site-packages/pip (python 3.11)'\n\n\n\nif sys.platform == 'win32':\n assert 'ipynb' in run('cmd /c dir /p')\n assert 'ipynb' in run(['cmd', '/c', 'dir', '/p'])\n assert 'ipynb' in run('cmd', '/c', 'dir', '/p')\nelse:\n assert 'ipynb' in run('ls -ls')\n assert 'ipynb' in run(['ls', '-l'])\n assert 'ipynb' in run('ls', '-l')\n\nSome commands fail in non-error situations, like grep. Use ignore_ex in those cases, which will return a tuple of stdout and returncode:\n\nif sys.platform == 'win32':\n test_eq(run('cmd /c findstr asdfds 00_test.ipynb', ignore_ex=True)[0], 1)\nelse:\n test_eq(run('grep asdfds 00_test.ipynb', ignore_ex=True)[0], 1)\n\nrun automatically decodes returned bytes to a str. Use as_bytes to skip that:\n\nif sys.platform == 'win32':\n test_eq(run('cmd /c echo hi'), 'hi')\nelse:\n test_eq(run('echo hi', as_bytes=True), b'hi\\n')\n\n\nsource\n\n\n\n\n open_file (fn, mode='r', **kwargs)\n\nOpen a file, with optional compression if gz or bz2 suffix\n\nsource\n\n\n\n\n save_pickle (fn, o)\n\nSave a pickle file, to a file name or opened file\n\nsource\n\n\n\n\n load_pickle (fn)\n\nLoad a pickle file from a file name or opened file\n\nfor suf in '.pkl','.bz2','.gz':\n # delete=False is added for Windows\n # https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file\n with tempfile.NamedTemporaryFile(suffix=suf, delete=False) as f:\n fn = Path(f.name)\n save_pickle(fn, 't')\n t = load_pickle(fn)\n f.close()\n test_eq(t,'t')\n\n\nsource\n\n\n\n\n parse_env (s:str=None, fn:Union[str,pathlib.Path]=None)\n\nParse a shell-style environment string or file\n\ntestf = \"\"\"# comment\n # another comment\n export FOO=\"bar#baz\"\nBAR=thing # comment \"ok\"\n baz='thong'\nQUX=quux\nexport ZAP = \"zip\" # more comments\n FOOBAR = 42 # trailing space and comment\"\"\"\n\nexp = dict(FOO='bar#baz', BAR='thing', baz='thong', QUX='quux', ZAP='zip', FOOBAR='42')\n\ntest_eq(parse_env(testf), exp)\n\n\nsource\n\n\n\n\n expand_wildcards (code)\n\nExpand all wildcard imports in the given code string.\n\ninp = \"\"\"from math import *\nfrom os import *\nfrom random import *\ndef func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)\"\"\"\n\nexp = \"\"\"from math import pi, sin\nfrom os import path\nfrom random import randint\ndef func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)\"\"\"\n\ntest_eq(expand_wildcards(inp), exp)\n\ninp = \"\"\"from itertools import *\ndef func(): pass\"\"\"\ntest_eq(expand_wildcards(inp), inp)\n\ninp = \"\"\"def outer():\n from math import *\n def inner():\n from os import *\n return sin(pi) + path.join('a', 'b')\"\"\"\n\nexp = \"\"\"def outer():\n from math import pi, sin\n def inner():\n from os import path\n return sin(pi) + path.join('a', 'b')\"\"\"\n\ntest_eq(expand_wildcards(inp), exp)", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "xtras.html#file-functions", + "href": "xtras.html#file-functions", + "title": "Utility functions", + "section": "", + "text": "Utilities (other than extensions to Pathlib.Path) for dealing with IO.\n\nsource\n\n\n\n walk (path:pathlib.Path|str, symlinks:bool=True, keep_file:<built-\n infunctioncallable>=<function ret_true>, keep_folder:<built-\n infunctioncallable>=<function ret_true>, skip_folder:<built-\n infunctioncallable>=<function ret_false>, func:<built-\n infunctioncallable>=<function join>, ret_folders:bool=False)\n\nGenerator version of os.walk, using functions to filter files and folders\n\n\n\n\n\n\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\npath\nPath | str\n\npath to start searching\n\n\nsymlinks\nbool\nTrue\nfollow symlinks?\n\n\nkeep_file\ncallable\nret_true\nfunction that returns True for wanted files\n\n\nkeep_folder\ncallable\nret_true\nfunction that returns True for folders to enter\n\n\nskip_folder\ncallable\nret_false\nfunction that returns True for folders to skip\n\n\nfunc\ncallable\njoin\nfunction to apply to each matched file\n\n\nret_folders\nbool\nFalse\nreturn folders, not just files\n\n\n\n\nsource\n\n\n\n\n globtastic (path:pathlib.Path|str, recursive:bool=True,\n symlinks:bool=True, file_glob:str=None, file_re:str=None,\n folder_re:str=None, skip_file_glob:str=None,\n skip_file_re:str=None, skip_folder_re:str=None, func:<built-\n infunctioncallable>=<function join>, ret_folders:bool=False)\n\nA more powerful glob, including regex matches, symlink handling, and skip parameters\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\npath\nPath | str\n\npath to start searching\n\n\nrecursive\nbool\nTrue\nsearch subfolders\n\n\nsymlinks\nbool\nTrue\nfollow symlinks?\n\n\nfile_glob\nstr\nNone\nOnly include files matching glob\n\n\nfile_re\nstr\nNone\nOnly include files matching regex\n\n\nfolder_re\nstr\nNone\nOnly enter folders matching regex\n\n\nskip_file_glob\nstr\nNone\nSkip files matching glob\n\n\nskip_file_re\nstr\nNone\nSkip files matching regex\n\n\nskip_folder_re\nstr\nNone\nSkip folders matching regex,\n\n\nfunc\ncallable\njoin\nfunction to apply to each matched file\n\n\nret_folders\nbool\nFalse\nreturn folders, not just files\n\n\nReturns\nL\n\nPaths to matched files\n\n\n\n\nglobtastic('.', skip_folder_re='^[_.]', folder_re='core', file_glob='*.*py*', file_re='c')\n\n(#5) ['./fastcore/docments.py','./fastcore/dispatch.py','./fastcore/basics.py','./fastcore/docscrape.py','./fastcore/script.py']\n\n\n\nsource\n\n\n\n\n maybe_open (f, mode='r', **kwargs)\n\nContext manager: open f if it is a path (and close on exit)\nThis is useful for functions where you want to accept a path or file. maybe_open will not close your file handle if you pass one in.\n\ndef _f(fn):\n with maybe_open(fn) as f: return f.encoding\n\nfname = '00_test.ipynb'\nsys_encoding = 'cp1252' if sys.platform == 'win32' else 'UTF-8'\ntest_eq(_f(fname), sys_encoding)\nwith open(fname) as fh: test_eq(_f(fh), sys_encoding)\n\nFor example, we can use this to reimplement imghdr.what from the Python standard library, which is written in Python 3.9 as:\n\nfrom fastcore import imghdr\n\n\ndef what(file, h=None):\n f = None\n try:\n if h is None:\n if isinstance(file, (str,os.PathLike)):\n f = open(file, 'rb')\n h = f.read(32)\n else:\n location = file.tell()\n h = file.read(32)\n file.seek(location)\n for tf in imghdr.tests:\n res = tf(h, f)\n if res: return res\n finally:\n if f: f.close()\n return None\n\nHere’s an example of the use of this function:\n\nfname = 'images/puppy.jpg'\nwhat(fname)\n\n'jpeg'\n\n\nWith maybe_open, Self, and L.map_first, we can rewrite this in a much more concise and (in our opinion) clear way:\n\ndef what(file, h=None):\n if h is None:\n with maybe_open(file, 'rb') as f: h = f.peek(32)\n return L(imghdr.tests).map_first(Self(h,file))\n\n…and we can check that it still works:\n\ntest_eq(what(fname), 'jpeg')\n\n…along with the version passing a file handle:\n\nwith open(fname,'rb') as f: test_eq(what(f), 'jpeg')\n\n…along with the h parameter version:\n\nwith open(fname,'rb') as f: test_eq(what(None, h=f.read(32)), 'jpeg')\n\n\nsource\n\n\n\n\n mkdir (path, exist_ok=False, parents=False, overwrite=False, **kwargs)\n\nCreates and returns a directory defined by path, optionally removing previous existing directory if overwrite is True\n\nwith tempfile.TemporaryDirectory() as d:\n path = Path(os.path.join(d, 'new_dir'))\n new_dir = mkdir(path)\n assert new_dir.exists()\n test_eq(new_dir, path)\n \n # test overwrite\n with open(new_dir/'test.txt', 'w') as f: f.writelines('test')\n test_eq(len(list(walk(new_dir))), 1) # assert file is present\n new_dir = mkdir(new_dir, overwrite=True)\n test_eq(len(list(walk(new_dir))), 0) # assert file was deleted\n\n\nsource\n\n\n\n\n image_size (fn)\n\nTuple of (w,h) for png, gif, or jpg; None otherwise\n\ntest_eq(image_size(fname), (1200,803))\n\n\nsource\n\n\n\n\n bunzip (fn)\n\nbunzip fn, raising exception if output already exists\n\nf = Path('files/test.txt')\nif f.exists(): f.unlink()\nbunzip('files/test.txt.bz2')\nt = f.open().readlines()\ntest_eq(len(t),1)\ntest_eq(t[0], 'test\\n')\nf.unlink()\n\n\nsource\n\n\n\n\n loads (s, **kw)\n\nSame as json.loads, but handles None\n\nsource\n\n\n\n\n loads_multi (s:str)\n\nGenerator of >=0 decoded json dicts, possibly with non-json ignored text at start and end\n\ntst = \"\"\"\n# ignored\n{ \"a\":1 }\nhello\n{\n\"b\":2\n}\n\"\"\"\n\ntest_eq(list(loads_multi(tst)), [{'a': 1}, {'b': 2}])\n\n\nsource\n\n\n\n\n dumps (obj, **kw)\n\nSame as json.dumps, but uses ujson if available\n\nsource\n\n\n\n\n untar_dir (fname, dest, rename=False, overwrite=False)\n\nuntar file into dest, creating a directory if the root contains more than one item\n\ndef test_untar(foldername, rename=False, **kwargs):\n with tempfile.TemporaryDirectory() as d:\n nm = os.path.join(d, 'a')\n shutil.make_archive(nm, 'gztar', **kwargs)\n with tempfile.TemporaryDirectory() as d2:\n d2 = Path(d2)\n untar_dir(nm+'.tar.gz', d2, rename=rename)\n test_eq(d2.ls(), [d2/foldername])\n\nIf the contents of fname contain just one file or directory, it is placed directly in dest:\n\n# using `base_dir` in `make_archive` results in `images` directory included in file names\ntest_untar('images', base_dir='images')\n\nIf rename then the directory created is named based on the archive, without extension:\n\ntest_untar('a', base_dir='images', rename=True)\n\nIf the contents of fname contain multiple files and directories, a new folder in dest is created with the same name as fname (but without extension):\n\n# using `root_dir` in `make_archive` results in `images` directory *not* included in file names\ntest_untar('a', root_dir='images')\n\n\nsource\n\n\n\n\n repo_details (url)\n\nTuple of owner,name from ssh or https git repo url\n\ntest_eq(repo_details('https://github.com/fastai/fastai.git'), ['fastai', 'fastai'])\ntest_eq(repo_details('git@github.com:fastai/nbdev.git\\n'), ['fastai', 'nbdev'])\n\n\nsource\n\n\n\n\n run (cmd, *rest, same_in_win=False, ignore_ex=False, as_bytes=False,\n stderr=False)\n\nPass cmd (splitting with shlex if string) to subprocess.run; return stdout; raise IOError if fails\nYou can pass a string (which will be split based on standard shell rules), a list, or pass args directly:\n\nrun('echo', same_in_win=True)\nrun('pip', '--version', same_in_win=True)\nrun(['pip', '--version'], same_in_win=True)\n\n'pip 23.3.1 from /Users/jhoward/miniconda3/lib/python3.11/site-packages/pip (python 3.11)'\n\n\n\nif sys.platform == 'win32':\n assert 'ipynb' in run('cmd /c dir /p')\n assert 'ipynb' in run(['cmd', '/c', 'dir', '/p'])\n assert 'ipynb' in run('cmd', '/c', 'dir', '/p')\nelse:\n assert 'ipynb' in run('ls -ls')\n assert 'ipynb' in run(['ls', '-l'])\n assert 'ipynb' in run('ls', '-l')\n\nSome commands fail in non-error situations, like grep. Use ignore_ex in those cases, which will return a tuple of stdout and returncode:\n\nif sys.platform == 'win32':\n test_eq(run('cmd /c findstr asdfds 00_test.ipynb', ignore_ex=True)[0], 1)\nelse:\n test_eq(run('grep asdfds 00_test.ipynb', ignore_ex=True)[0], 1)\n\nrun automatically decodes returned bytes to a str. Use as_bytes to skip that:\n\nif sys.platform == 'win32':\n test_eq(run('cmd /c echo hi'), 'hi')\nelse:\n test_eq(run('echo hi', as_bytes=True), b'hi\\n')\n\n\nsource\n\n\n\n\n open_file (fn, mode='r', **kwargs)\n\nOpen a file, with optional compression if gz or bz2 suffix\n\nsource\n\n\n\n\n save_pickle (fn, o)\n\nSave a pickle file, to a file name or opened file\n\nsource\n\n\n\n\n load_pickle (fn)\n\nLoad a pickle file from a file name or opened file\n\nfor suf in '.pkl','.bz2','.gz':\n # delete=False is added for Windows\n # https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file\n with tempfile.NamedTemporaryFile(suffix=suf, delete=False) as f:\n fn = Path(f.name)\n save_pickle(fn, 't')\n t = load_pickle(fn)\n f.close()\n test_eq(t,'t')\n\n\nsource\n\n\n\n\n parse_env (s:str=None, fn:Union[str,pathlib.Path]=None)\n\nParse a shell-style environment string or file\n\ntestf = \"\"\"# comment\n # another comment\n export FOO=\"bar#baz\"\nBAR=thing # comment \"ok\"\n baz='thong'\nQUX=quux\nexport ZAP = \"zip\" # more comments\n FOOBAR = 42 # trailing space and comment\"\"\"\n\nexp = dict(FOO='bar#baz', BAR='thing', baz='thong', QUX='quux', ZAP='zip', FOOBAR='42')\n\ntest_eq(parse_env(testf), exp)\n\n\nsource\n\n\n\n\n expand_wildcards (code)\n\nExpand all wildcard imports in the given code string.\n\ninp = \"\"\"from math import *\nfrom os import *\nfrom random import *\ndef func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)\"\"\"\n\nexp = \"\"\"from math import pi, sin\nfrom os import path\nfrom random import randint\ndef func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)\"\"\"\n\ntest_eq(expand_wildcards(inp), exp)\n\ninp = \"\"\"from itertools import *\ndef func(): pass\"\"\"\ntest_eq(expand_wildcards(inp), inp)\n\ninp = \"\"\"def outer():\n from math import *\n def inner():\n from os import *\n return sin(pi) + path.join('a', 'b')\"\"\"\n\nexp = \"\"\"def outer():\n from math import pi, sin\n def inner():\n from os import path\n return sin(pi) + path.join('a', 'b')\"\"\"\n\ntest_eq(expand_wildcards(inp), exp)", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "xtras.html#collections", + "href": "xtras.html#collections", + "title": "Utility functions", + "section": "Collections", + "text": "Collections\n\nsource\n\ndict2obj\n\n dict2obj (d, list_func=<class 'fastcore.foundation.L'>, dict_func=<class\n 'fastcore.basics.AttrDict'>)\n\nConvert (possibly nested) dicts (or lists of dicts) to AttrDict\nThis is a convenience to give you “dotted” access to (possibly nested) dictionaries, e.g:\n\nd1 = dict(a=1, b=dict(c=2,d=3))\nd2 = dict2obj(d1)\ntest_eq(d2.b.c, 2)\ntest_eq(d2.b['c'], 2)\n\nIt can also be used on lists of dicts.\n\n_list_of_dicts = [d1, d1]\nds = dict2obj(_list_of_dicts)\ntest_eq(ds[0].b.c, 2)\n\n\nsource\n\n\nobj2dict\n\n obj2dict (d)\n\nConvert (possibly nested) AttrDicts (or lists of AttrDicts) to dict\nobj2dict can be used to reverse what is done by dict2obj:\n\ntest_eq(obj2dict(d2), d1)\ntest_eq(obj2dict(ds), _list_of_dicts)\n\n\nsource\n\n\nrepr_dict\n\n repr_dict (d)\n\nPrint nested dicts and lists, such as returned by dict2obj\n\nprint(repr_dict(d2))\n\n- a: 1\n- b: \n - c: 2\n - d: 3\n\n\n\nsource\n\n\nis_listy\n\n is_listy (x)\n\nisinstance(x, (tuple,list,L,slice,Generator))\n\nassert is_listy((1,))\nassert is_listy([1])\nassert is_listy(L([1]))\nassert is_listy(slice(2))\nassert not is_listy(array([1]))\n\n\nsource\n\n\nmapped\n\n mapped (f, it)\n\nmap f over it, unless it’s not listy, in which case return f(it)\n\ndef _f(x,a=1): return x-a\n\ntest_eq(mapped(_f,1),0)\ntest_eq(mapped(_f,[1,2]),[0,1])\ntest_eq(mapped(_f,(1,)),(0,))", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "xtras.html#extensions-to-pathlib.path", + "href": "xtras.html#extensions-to-pathlib.path", + "title": "Utility functions", + "section": "Extensions to Pathlib.Path", + "text": "Extensions to Pathlib.Path\nThe following methods are added to the standard python libary Pathlib.Path.\n\nsource\n\nPath.readlines\n\n Path.readlines (hint=-1, encoding='utf8')\n\nRead the content of self\n\nsource\n\n\nPath.read_json\n\n Path.read_json (encoding=None, errors=None)\n\nSame as read_text followed by loads\n\nsource\n\n\nPath.mk_write\n\n Path.mk_write (data, encoding=None, errors=None, mode=511)\n\nMake all parent dirs of self, and write data\n\nsource\n\n\nPath.relpath\n\n Path.relpath (start=None)\n\nSame as os.path.relpath, but returns a Path, and resolves symlinks\n\np = Path('../fastcore/').resolve()\np\n\nPath('/Users/jhoward/Documents/GitHub/fastcore/fastcore')\n\n\n\np.relpath(Path.cwd())\n\nPath('../fastcore')\n\n\n\nsource\n\n\nPath.ls\n\n Path.ls (n_max=None, file_type=None, file_exts=None)\n\nContents of path as a list\nWe add an ls() method to pathlib.Path which is simply defined as list(Path.iterdir()), mainly for convenience in REPL environments such as notebooks.\n\npath = Path()\nt = path.ls()\nassert len(t)>0\nt1 = path.ls(10)\ntest_eq(len(t1), 10)\nt2 = path.ls(file_exts='.ipynb')\nassert len(t)>len(t2)\nt[0]\n\nPath('000_tour.ipynb')\n\n\nYou can also pass an optional file_type MIME prefix and/or a list of file extensions.\n\nlib_path = (path/'../fastcore')\ntxt_files=lib_path.ls(file_type='text')\nassert len(txt_files) > 0 and txt_files[0].suffix=='.py'\nipy_files=path.ls(file_exts=['.ipynb'])\nassert len(ipy_files) > 0 and ipy_files[0].suffix=='.ipynb'\ntxt_files[0],ipy_files[0]\n\n(Path('../fastcore/shutil.py'), Path('000_tour.ipynb'))\n\n\n\nsource\n\n\nPath.__repr__\n\n Path.__repr__ ()\n\nReturn repr(self).\nfastai also updates the repr of Path such that, if Path.BASE_PATH is defined, all paths are printed relative to that path (as long as they are contained in Path.BASE_PATH:\n\nt = ipy_files[0].absolute()\ntry:\n Path.BASE_PATH = t.parent.parent\n test_eq(repr(t), f\"Path('nbs/{t.name}')\")\nfinally: Path.BASE_PATH = None\n\n\nsource\n\n\nPath.delete\n\n Path.delete ()\n\nDelete a file, symlink, or directory tree", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "xtras.html#reindexing-collections", + "href": "xtras.html#reindexing-collections", + "title": "Utility functions", + "section": "Reindexing Collections", + "text": "Reindexing Collections\n\nsource\n\nReindexCollection\n\n ReindexCollection (coll, idxs=None, cache=None, tfm=<function noop>)\n\nReindexes collection coll with indices idxs and optional LRU cache of size cache\nThis is useful when constructing batches or organizing data in a particular manner (i.e. for deep learning). This class is primarly used in organizing data for language models in fastai.\nYou can supply a custom index upon instantiation with the idxs argument, or you can call the reindex method to supply a new index for your collection.\nHere is how you can reindex a list such that the elements are reversed:\n\nrc=ReindexCollection(['a', 'b', 'c', 'd', 'e'], idxs=[4,3,2,1,0])\nlist(rc)\n\n['e', 'd', 'c', 'b', 'a']\n\n\nAlternatively, you can use the reindex method:\n\nsource\n\nReindexCollection.reindex\n\n ReindexCollection.reindex (idxs)\n\nReplace self.idxs with idxs\n\nrc=ReindexCollection(['a', 'b', 'c', 'd', 'e'])\nrc.reindex([4,3,2,1,0])\nlist(rc)\n\n['e', 'd', 'c', 'b', 'a']\n\n\nYou can optionally specify a LRU cache, which uses functools.lru_cache upon instantiation:\n\nsz = 50\nt = ReindexCollection(L.range(sz), cache=2)\n\n#trigger a cache hit by indexing into the same element multiple times\nt[0], t[0]\nt._get.cache_info()\n\nCacheInfo(hits=1, misses=1, maxsize=2, currsize=1)\n\n\nYou can optionally clear the LRU cache by calling the cache_clear method:\n\nsource\n\n\nReindexCollection.cache_clear\n\n ReindexCollection.cache_clear ()\n\nClear LRU cache\n\nsz = 50\nt = ReindexCollection(L.range(sz), cache=2)\n\n#trigger a cache hit by indexing into the same element multiple times\nt[0], t[0]\nt.cache_clear()\nt._get.cache_info()\n\nCacheInfo(hits=0, misses=0, maxsize=2, currsize=0)\n\n\n\nsource\n\n\nReindexCollection.shuffle\n\n ReindexCollection.shuffle ()\n\nRandomly shuffle indices\nNote that an ordered index is automatically constructed for the data structure even if one is not supplied.\n\nrc=ReindexCollection(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])\nrc.shuffle()\nlist(rc)\n\n['b', 'a', 'd', 'e', 'c', 'g', 'h', 'f']\n\n\n\nsz = 50\nt = ReindexCollection(L.range(sz), cache=2)\ntest_eq(list(t), range(sz))\ntest_eq(t[sz-1], sz-1)\ntest_eq(t._get.cache_info().hits, 1)\nt.shuffle()\ntest_eq(t._get.cache_info().hits, 1)\ntest_ne(list(t), range(sz))\ntest_eq(set(t), set(range(sz)))\nt.cache_clear()\ntest_eq(t._get.cache_info().hits, 0)\ntest_eq(t.count(0), 1)", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "xtras.html#other-helpers", + "href": "xtras.html#other-helpers", + "title": "Utility functions", + "section": "Other Helpers", + "text": "Other Helpers\n\nsource\n\nget_source_link\n\n get_source_link (func)\n\nReturn link to func in source code\nget_source_link allows you get a link to source code related to an object. For nbdev related projects such as fastcore, we can get the full link to a GitHub repo. For nbdev projects, be sure to properly set the git_url in settings.ini (derived from lib_name and branch on top of the prefix you will need to adapt) so that those links are correct.\nFor example, below we get the link to fastcore.test.test_eq:\n\nfrom fastcore.test import test_eq\n\n\nassert 'fastcore/test.py' in get_source_link(test_eq)\nassert get_source_link(test_eq).startswith('https://github.com/fastai/fastcore')\nget_source_link(test_eq)\n\n'https://github.com/fastai/fastcore/tree/master/fastcore/test.py#L35'\n\n\n\nsource\n\n\ntruncstr\n\n truncstr (s:str, maxlen:int, suf:str='…', space='')\n\nTruncate s to length maxlen, adding suffix suf if truncated\n\nw = 'abacadabra'\ntest_eq(truncstr(w, 10), w)\ntest_eq(truncstr(w, 5), 'abac…')\ntest_eq(truncstr(w, 5, suf=''), 'abaca')\ntest_eq(truncstr(w, 11, space='_'), w+\"_\")\ntest_eq(truncstr(w, 10, space='_'), w[:-1]+'…')\ntest_eq(truncstr(w, 5, suf='!!'), 'aba!!')\n\n\nsource\n\n\nsparkline\n\n sparkline (data, mn=None, mx=None, empty_zero=False)\n\nSparkline for data, with Nones (and zero, if empty_zero) shown as empty column\n\ndata = [9,6,None,1,4,0,8,15,10]\nprint(f'without \"empty_zero\": {sparkline(data, empty_zero=False)}')\nprint(f' with \"empty_zero\": {sparkline(data, empty_zero=True )}')\n\nwithout \"empty_zero\": ▅▂ ▁▂▁▃▇▅\n with \"empty_zero\": ▅▂ ▁▂ ▃▇▅\n\n\nYou can set a maximum and minimum for the y-axis of the sparkline with the arguments mn and mx respectively:\n\nsparkline([1,2,3,400], mn=0, mx=3)\n\n'▂▅▇▇'\n\n\n\nsource\n\n\nmodify_exception\n\n modify_exception (e:Exception, msg:str=None, replace:bool=False)\n\nModifies e with a custom message attached\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\ne\nException\n\nAn exception\n\n\nmsg\nstr\nNone\nA custom message\n\n\nreplace\nbool\nFalse\nWhether to replace e.args with [msg]\n\n\nReturns\nException\n\n\n\n\n\n\nmsg = \"This is my custom message!\"\n\ntest_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(), None)), contains='')\ntest_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(), msg)), contains=msg)\ntest_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(\"The first message\"), msg)), contains=\"The first message This is my custom message!\")\ntest_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(\"The first message\"), msg, True)), contains=\"This is my custom message!\")\n\n\nsource\n\n\nround_multiple\n\n round_multiple (x, mult, round_down=False)\n\nRound x to nearest multiple of mult\n\ntest_eq(round_multiple(63,32), 64)\ntest_eq(round_multiple(50,32), 64)\ntest_eq(round_multiple(40,32), 32)\ntest_eq(round_multiple( 0,32), 0)\ntest_eq(round_multiple(63,32, round_down=True), 32)\ntest_eq(round_multiple((63,40),32), (64,32))\n\n\nsource\n\n\nset_num_threads\n\n set_num_threads (nt)\n\nGet numpy (and others) to use nt threads\nThis sets the number of threads consistently for many tools, by:\n\nSet the following environment variables equal to nt: OPENBLAS_NUM_THREADS,NUMEXPR_NUM_THREADS,OMP_NUM_THREADS,MKL_NUM_THREADS\nSets nt threads for numpy and pytorch.\n\n\nsource\n\n\njoin_path_file\n\n join_path_file (file, path, ext='')\n\nReturn path/file if file is a string or a Path, file otherwise\n\npath = Path.cwd()/'_tmp'/'tst'\nf = join_path_file('tst.txt', path)\nassert path.exists()\ntest_eq(f, path/'tst.txt')\nwith open(f, 'w') as f_: assert join_path_file(f_, path) == f_\nshutil.rmtree(Path.cwd()/'_tmp')\n\n\nsource\n\n\nautostart\n\n autostart (g)\n\nDecorator that automatically starts a generator\n\nsource\n\nEventTimer\n\n EventTimer (store=5, span=60)\n\nAn event timer with history of store items of time span\nAdd events with add, and get number of events and their frequency (freq).\n\n# Random wait function for testing\ndef _randwait(): yield from (sleep(random.random()/200) for _ in range(100))\n\nc = EventTimer(store=5, span=0.03)\nfor o in _randwait(): c.add(1)\nprint(f'Num Events: {c.events}, Freq/sec: {c.freq:.01f}')\nprint('Most recent: ', sparkline(c.hist), *L(c.hist).map('{:.01f}'))\n\nNum Events: 7, Freq/sec: 346.4\nMost recent: ▁▇▃▅▁ 295.9 396.4 324.8 356.6 262.6\n\n\n\nsource\n\n\n\nstringfmt_names\n\n stringfmt_names (s:str)\n\nUnique brace-delimited names in s\n\ns = '/pulls/{pull_number}/reviews/{review_id}'\ntest_eq(stringfmt_names(s), ['pull_number','review_id'])\n\n\nsource\n\nPartialFormatter\n\n PartialFormatter ()\n\nA string.Formatter that doesn’t error on missing fields, and tracks missing fields and unused args\n\nsource\n\n\n\npartial_format\n\n partial_format (s:str, **kwargs)\n\nstring format s, ignoring missing field errors, returning missing and extra fields\nThe result is a tuple of (formatted_string,missing_fields,extra_fields), e.g:\n\nres,missing,xtra = partial_format(s, pull_number=1, foo=2)\ntest_eq(res, '/pulls/1/reviews/{review_id}')\ntest_eq(missing, ['review_id'])\ntest_eq(xtra, {'foo':2})\n\n\nsource\n\n\nutc2local\n\n utc2local (dt:datetime.datetime)\n\nConvert dt from UTC to local time\n\ndt = datetime(2000,1,1,12)\nprint(f'{dt} UTC is {utc2local(dt)} local time')\n\n2000-01-01 12:00:00 UTC is 2000-01-01 22:00:00+10:00 local time\n\n\n\nsource\n\n\nlocal2utc\n\n local2utc (dt:datetime.datetime)\n\nConvert dt from local to UTC time\n\nprint(f'{dt} local is {local2utc(dt)} UTC time')\n\n2000-01-01 12:00:00 local is 2000-01-01 02:00:00+00:00 UTC time\n\n\n\nsource\n\n\ntrace\n\n trace (f)\n\nAdd set_trace to an existing function f\nYou can add a breakpoint to an existing function, e.g:\nPath.cwd = trace(Path.cwd)\nPath.cwd()\nNow, when the function is called it will drop you into the debugger. Note, you must issue the s command when you begin to step into the function that is being traced.\n\nsource\n\n\nmodified_env\n\n modified_env (*delete, **replace)\n\nContext manager temporarily modifying os.environ by deleting delete and replacing replace\n\n# USER isn't in Cloud Linux Environments\nenv_test = 'USERNAME' if sys.platform == \"win32\" else 'SHELL'\noldusr = os.environ[env_test]\n\nreplace_param = {env_test: 'a'}\nwith modified_env('PATH', **replace_param):\n test_eq(os.environ[env_test], 'a')\n assert 'PATH' not in os.environ\n\nassert 'PATH' in os.environ\ntest_eq(os.environ[env_test], oldusr)\n\n\nsource\n\nContextManagers\n\n ContextManagers (mgrs)\n\nWrapper for contextlib.ExitStack which enters a collection of context managers\n\nsource\n\n\n\nshufflish\n\n shufflish (x, pct=0.04)\n\nRandomly relocate items of x up to pct of len(x) from their starting location\n\nsource\n\n\nconsole_help\n\n console_help (libname:str)\n\nShow help for all console scripts from libname\n\n\n\n\nType\nDetails\n\n\n\n\nlibname\nstr\nname of library for console script listing\n\n\n\n\nsource\n\n\nhl_md\n\n hl_md (s, lang='xml', show=True)\n\nSyntax highlight s using lang.\nWhen we display code in a notebook, it’s nice to highlight it, so we create a function to simplify that:\n\nhl_md('<test><xml foo=\"bar\">a child</xml></test>')\n\n<test><xml foo=\"bar\">a child</xml></test>\n\n\n\nsource\n\n\ntype2str\n\n type2str (typ:type)\n\nStringify typ\n\ntest_eq(type2str(Optional[float]), 'Union[float, None]')\n\n\nsource\n\n\ndataclass_src\n\n dataclass_src (cls)\n\n\nDC = make_dataclass('DC', [('x', int), ('y', Optional[float], None), ('z', float, None)])\nprint(dataclass_src(DC))\n\n@dataclass\nclass DC:\n x: int\n y: Union[float, None] = None\n z: float = None\n\n\n\n\nsource\n\n\nUnset\n\n Unset (value, names=None, module=None, qualname=None, type=None, start=1)\n\nAn enumeration.\n\nsource\n\n\nnullable_dc\n\n nullable_dc (cls)\n\nLike dataclass, but default of UNSET added to fields without defaults\n\n@nullable_dc\nclass Person: name: str; age: int; city: str = \"Unknown\"\nPerson(name=\"Bob\")\n\nPerson(name='Bob', age=UNSET, city='Unknown')\n\n\n\nsource\n\n\nmake_nullable\n\n make_nullable (clas)\n\n\n@dataclass\nclass Person: name: str; age: int; city: str = \"Unknown\"\n\nmake_nullable(Person)\nPerson(\"Bob\", city='NY')\n\nPerson(name='Bob', age=UNSET, city='NY')\n\n\n\nPerson(name=\"Bob\")\n\nPerson(name='Bob', age=UNSET, city='Unknown')\n\n\n\nPerson(\"Bob\", 34)\n\nPerson(name='Bob', age=34, city='Unknown')\n\n\n\nsource\n\n\nflexiclass\n\n flexiclass (cls)\n\nConvert cls into a dataclass like make_nullable\nThis can be used as a decorator…\n\n@flexiclass\nclass Person: name: str; age: int; city: str = \"Unknown\"\n\nbob = Person(name=\"Bob\")\nbob\n\nPerson(name='Bob', age=UNSET, city='Unknown')\n\n\n…or can update the behavior of an existing class (or dataclass):\n\nclass Person: name: str; age: int; city: str = \"Unknown\"\n\nflexiclass(Person)\nbob = Person(name=\"Bob\")\nbob\n\nPerson(name='Bob', age=UNSET, city='Unknown')\n\n\n\nsource\n\n\nasdict\n\n asdict (o)\n\nConvert o to a dict, supporting dataclasses, namedtuples, iterables, and __dict__ attrs.\nAny UNSET values are not included.\n\nasdict(bob)\n\n{'name': 'Bob', 'city': 'Unknown'}\n\n\nTo customise dict conversion behavior for a class, implement the _asdict method (this is used in the Python stdlib for named tuples).\n\nsource\n\n\nis_typeddict\n\n is_typeddict (cls:type)\n\nCheck if cls is a TypedDict\n\nclass MyDict(TypedDict): name:str\n\nassert is_typeddict(MyDict)\nassert not is_typeddict({'a':1})\n\n\nsource\n\n\nis_namedtuple\n\n is_namedtuple (cls)\n\nTrue if cls is a namedtuple type\n\nassert is_namedtuple(namedtuple('tst', ['a']))\nassert not is_namedtuple(tuple)\n\n\nsource\n\n\nflexicache\n\n flexicache (*funcs, maxsize=128)\n\nLike lru_cache, but customisable with policy funcs\nThis is a flexible lru cache function that you can pass a list of functions to. Those functions define the cache eviction policy. For instance, time_policy is provided for time-based cache eviction, and mtime_policy evicts based on a file’s modified-time changing. The policy functions are passed the last value that function returned was (initially None), and return a new value to indicate the cache has expired. When the cache expires, all functions are called with None to force getting new values.\n\nsource\n\n\ntime_policy\n\n time_policy (seconds)\n\nA flexicache policy that expires cached items after seconds have passed\n\nsource\n\n\nmtime_policy\n\n mtime_policy (filepath)\n\nA flexicache policy that expires cached items after filepath modified-time changes\n\n@flexicache(time_policy(10), mtime_policy('000_tour.ipynb'))\ndef cached_func(x, y): return x+y\n\ncached_func(1,2)\n\n3\n\n\n\n@flexicache(time_policy(10), mtime_policy('000_tour.ipynb'))\nasync def cached_func(x, y): return x+y\n\nawait cached_func(1,2)\nawait cached_func(1,2)\n\n3\n\n\n\nsource\n\n\ntimed_cache\n\n timed_cache (seconds=60, maxsize=128)\n\nLike lru_cache, but also with time-based eviction\nThis function is a small convenience wrapper for using flexicache with time_policy.\n\n@timed_cache(seconds=0.05, maxsize=2)\ndef cached_func(x): return x * 2, time()\n\n# basic caching\nresult1, time1 = cached_func(2)\ntest_eq(result1, 4)\nsleep(0.001)\nresult2, time2 = cached_func(2)\ntest_eq(result2, 4)\ntest_eq(time1, time2)\n\n# caching different values\nresult3, _ = cached_func(3)\ntest_eq(result3, 6)\n\n# maxsize\n_, time4 = cached_func(4)\n_, time2_new = cached_func(2)\ntest_close(time2, time2_new, eps=0.1)\n_, time3_new = cached_func(3)\ntest_ne(time3_new, time())\n\n# time expiration\nsleep(0.05)\n_, time4_new = cached_func(4)\ntest_ne(time4_new, time())", + "crumbs": [ + "Utility functions" + ] + }, + { + "objectID": "foundation.html", + "href": "foundation.html", + "title": "Foundation", + "section": "", + "text": "source\n\n\n\n working_directory (path)\n\nChange working directory to path and return to previous on exit.\n\nsource\n\n\n\n\n add_docs (cls, cls_doc=None, **docs)\n\nCopy values from docs to cls docstrings, and confirm all public methods are documented\nadd_docs allows you to add docstrings to a class and its associated methods. This function allows you to group docstrings together seperate from your code, which enables you to define one-line functions as well as organize your code more succintly. We believe this confers a number of benefits which we discuss in our style guide.\nSuppose you have the following undocumented class:\n\nclass T:\n def foo(self): pass\n def bar(self): pass\n\nYou can add documentation to this class like so:\n\nadd_docs(T, cls_doc=\"A docstring for the class.\",\n foo=\"The foo method.\",\n bar=\"The bar method.\")\n\nNow, docstrings will appear as expected:\n\ntest_eq(T.__doc__, \"A docstring for the class.\")\ntest_eq(T.foo.__doc__, \"The foo method.\")\ntest_eq(T.bar.__doc__, \"The bar method.\")\n\nadd_docs also validates that all of your public methods contain a docstring. If one of your methods is not documented, it will raise an error:\n\nclass T:\n def foo(self): pass\n def bar(self): pass\n\nf=lambda: add_docs(T, \"A docstring for the class.\", foo=\"The foo method.\")\ntest_fail(f, contains=\"Missing docs\")\n\n\nsource\n\n\n\n\n docs (cls)\n\nDecorator version of add_docs, using _docs dict\nInstead of using add_docs, you can use the decorator docs as shown below. Note that the docstring for the class can be set with the argument cls_doc:\n\n@docs\nclass _T:\n def f(self): pass\n def g(cls): pass\n \n _docs = dict(cls_doc=\"The class docstring\", \n f=\"The docstring for method f.\",\n g=\"A different docstring for method g.\")\n\n \ntest_eq(_T.__doc__, \"The class docstring\")\ntest_eq(_T.f.__doc__, \"The docstring for method f.\")\ntest_eq(_T.g.__doc__, \"A different docstring for method g.\")\n\nFor either the docs decorator or the add_docs function, you can still define your docstrings in the normal way. Below we set the docstring for the class as usual, but define the method docstrings through the _docs attribute:\n\n@docs\nclass _T:\n \"The class docstring\"\n def f(self): pass\n _docs = dict(f=\"The docstring for method f.\")\n\n \ntest_eq(_T.__doc__, \"The class docstring\")\ntest_eq(_T.f.__doc__, \"The docstring for method f.\")\n\n\n\n\n\n\n is_iter (o)\n\nTest whether o can be used in a for loop\n\nassert is_iter([1])\nassert not is_iter(array(1))\nassert is_iter(array([1,2]))\nassert (o for o in range(3))\n\n\nsource\n\n\n\n\n coll_repr (c, max_n=10)\n\nString repr of up to max_n items of (possibly lazy) collection c\ncoll_repr is used to provide a more informative __repr__ about list-like objects. coll_repr and is used by L to build a __repr__ that displays the length of a list in addition to a preview of a list.\nBelow is an example of the __repr__ string created for a list of 1000 elements:\n\ntest_eq(coll_repr(range(1000)), '(#1000) [0,1,2,3,4,5,6,7,8,9...]')\ntest_eq(coll_repr(range(1000), 5), '(#1000) [0,1,2,3,4...]')\ntest_eq(coll_repr(range(10), 5), '(#10) [0,1,2,3,4...]')\ntest_eq(coll_repr(range(5), 5), '(#5) [0,1,2,3,4]')\n\nWe can set the option max_n to optionally preview a specified number of items instead of the default:\n\ntest_eq(coll_repr(range(1000), max_n=5), '(#1000) [0,1,2,3,4...]')\n\n\nsource\n\n\n\n\n is_bool (x)\n\nCheck whether x is a bool or None\n\nsource\n\n\n\n\n mask2idxs (mask)\n\nConvert bool mask or index list to index L\n\ntest_eq(mask2idxs([False,True,False,True]), [1,3])\ntest_eq(mask2idxs(array([False,True,False,True])), [1,3])\ntest_eq(mask2idxs(array([1,2,3])), [1,2,3])\n\n\nsource\n\n\n\n\n cycle (o)\n\nLike itertools.cycle except creates list of Nones if o is empty\n\ntest_eq(itertools.islice(cycle([1,2,3]),5), [1,2,3,1,2])\ntest_eq(itertools.islice(cycle([]),3), [None]*3)\ntest_eq(itertools.islice(cycle(None),3), [None]*3)\ntest_eq(itertools.islice(cycle(1),3), [1,1,1])\n\n\nsource\n\n\n\n\n zip_cycle (x, *args)\n\nLike itertools.zip_longest but cycles through elements of all but first argument\n\ntest_eq(zip_cycle([1,2,3,4],list('abc')), [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'a')])\n\n\nsource\n\n\n\n\n is_indexer (idx)\n\nTest whether idx will index a single item in a list\nYou can, for example index a single item in a list with an integer or a 0-dimensional numpy array:\n\nassert is_indexer(1)\nassert is_indexer(np.array(1))\n\nHowever, you cannot index into single item in a list with another list or a numpy array with ndim > 0.\n\nassert not is_indexer([1, 2])\nassert not is_indexer(np.array([[1, 2], [3, 4]]))", + "crumbs": [ + "Foundation" + ] + }, + { + "objectID": "foundation.html#foundational-functions", + "href": "foundation.html#foundational-functions", + "title": "Foundation", + "section": "", + "text": "source\n\n\n\n working_directory (path)\n\nChange working directory to path and return to previous on exit.\n\nsource\n\n\n\n\n add_docs (cls, cls_doc=None, **docs)\n\nCopy values from docs to cls docstrings, and confirm all public methods are documented\nadd_docs allows you to add docstrings to a class and its associated methods. This function allows you to group docstrings together seperate from your code, which enables you to define one-line functions as well as organize your code more succintly. We believe this confers a number of benefits which we discuss in our style guide.\nSuppose you have the following undocumented class:\n\nclass T:\n def foo(self): pass\n def bar(self): pass\n\nYou can add documentation to this class like so:\n\nadd_docs(T, cls_doc=\"A docstring for the class.\",\n foo=\"The foo method.\",\n bar=\"The bar method.\")\n\nNow, docstrings will appear as expected:\n\ntest_eq(T.__doc__, \"A docstring for the class.\")\ntest_eq(T.foo.__doc__, \"The foo method.\")\ntest_eq(T.bar.__doc__, \"The bar method.\")\n\nadd_docs also validates that all of your public methods contain a docstring. If one of your methods is not documented, it will raise an error:\n\nclass T:\n def foo(self): pass\n def bar(self): pass\n\nf=lambda: add_docs(T, \"A docstring for the class.\", foo=\"The foo method.\")\ntest_fail(f, contains=\"Missing docs\")\n\n\nsource\n\n\n\n\n docs (cls)\n\nDecorator version of add_docs, using _docs dict\nInstead of using add_docs, you can use the decorator docs as shown below. Note that the docstring for the class can be set with the argument cls_doc:\n\n@docs\nclass _T:\n def f(self): pass\n def g(cls): pass\n \n _docs = dict(cls_doc=\"The class docstring\", \n f=\"The docstring for method f.\",\n g=\"A different docstring for method g.\")\n\n \ntest_eq(_T.__doc__, \"The class docstring\")\ntest_eq(_T.f.__doc__, \"The docstring for method f.\")\ntest_eq(_T.g.__doc__, \"A different docstring for method g.\")\n\nFor either the docs decorator or the add_docs function, you can still define your docstrings in the normal way. Below we set the docstring for the class as usual, but define the method docstrings through the _docs attribute:\n\n@docs\nclass _T:\n \"The class docstring\"\n def f(self): pass\n _docs = dict(f=\"The docstring for method f.\")\n\n \ntest_eq(_T.__doc__, \"The class docstring\")\ntest_eq(_T.f.__doc__, \"The docstring for method f.\")\n\n\n\n\n\n\n is_iter (o)\n\nTest whether o can be used in a for loop\n\nassert is_iter([1])\nassert not is_iter(array(1))\nassert is_iter(array([1,2]))\nassert (o for o in range(3))\n\n\nsource\n\n\n\n\n coll_repr (c, max_n=10)\n\nString repr of up to max_n items of (possibly lazy) collection c\ncoll_repr is used to provide a more informative __repr__ about list-like objects. coll_repr and is used by L to build a __repr__ that displays the length of a list in addition to a preview of a list.\nBelow is an example of the __repr__ string created for a list of 1000 elements:\n\ntest_eq(coll_repr(range(1000)), '(#1000) [0,1,2,3,4,5,6,7,8,9...]')\ntest_eq(coll_repr(range(1000), 5), '(#1000) [0,1,2,3,4...]')\ntest_eq(coll_repr(range(10), 5), '(#10) [0,1,2,3,4...]')\ntest_eq(coll_repr(range(5), 5), '(#5) [0,1,2,3,4]')\n\nWe can set the option max_n to optionally preview a specified number of items instead of the default:\n\ntest_eq(coll_repr(range(1000), max_n=5), '(#1000) [0,1,2,3,4...]')\n\n\nsource\n\n\n\n\n is_bool (x)\n\nCheck whether x is a bool or None\n\nsource\n\n\n\n\n mask2idxs (mask)\n\nConvert bool mask or index list to index L\n\ntest_eq(mask2idxs([False,True,False,True]), [1,3])\ntest_eq(mask2idxs(array([False,True,False,True])), [1,3])\ntest_eq(mask2idxs(array([1,2,3])), [1,2,3])\n\n\nsource\n\n\n\n\n cycle (o)\n\nLike itertools.cycle except creates list of Nones if o is empty\n\ntest_eq(itertools.islice(cycle([1,2,3]),5), [1,2,3,1,2])\ntest_eq(itertools.islice(cycle([]),3), [None]*3)\ntest_eq(itertools.islice(cycle(None),3), [None]*3)\ntest_eq(itertools.islice(cycle(1),3), [1,1,1])\n\n\nsource\n\n\n\n\n zip_cycle (x, *args)\n\nLike itertools.zip_longest but cycles through elements of all but first argument\n\ntest_eq(zip_cycle([1,2,3,4],list('abc')), [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'a')])\n\n\nsource\n\n\n\n\n is_indexer (idx)\n\nTest whether idx will index a single item in a list\nYou can, for example index a single item in a list with an integer or a 0-dimensional numpy array:\n\nassert is_indexer(1)\nassert is_indexer(np.array(1))\n\nHowever, you cannot index into single item in a list with another list or a numpy array with ndim > 0.\n\nassert not is_indexer([1, 2])\nassert not is_indexer(np.array([[1, 2], [3, 4]]))", + "crumbs": [ + "Foundation" + ] + }, + { + "objectID": "foundation.html#l-helpers", + "href": "foundation.html#l-helpers", + "title": "Foundation", + "section": "L helpers", + "text": "L helpers\n\nsource\n\nCollBase\n\n CollBase (items)\n\nBase class for composing a list of items\nColBase is a base class that emulates the functionality of a python list:\n\nclass _T(CollBase): pass\nl = _T([1,2,3,4,5])\n\ntest_eq(len(l), 5) # __len__\ntest_eq(l[-1], 5); test_eq(l[0], 1) #__getitem__\nl[2] = 100; test_eq(l[2], 100) # __set_item__\ndel l[0]; test_eq(len(l), 4) # __delitem__\ntest_eq(str(l), '[2, 100, 4, 5]') # __repr__\n\n\nsource\n\n\nL\n\n L (x=None, *args, **kwargs)\n\nBehaves like a list of items but can also index with list of indices or masks\nL is a drop in replacement for a python list. Inspired by NumPy, L, supports advanced indexing and has additional methods (outlined below) that provide additional functionality and encourage simple expressive code. For example, the code below takes a list of pairs, selects the second item of each pair, takes its absolute value, filters items greater than 4, and adds them up:\n\nfrom fastcore.utils import gt\n\n\nd = dict(a=1,b=-5,d=6,e=9).items()\ntest_eq(L(d).itemgot(1).map(abs).filter(gt(4)).sum(), 20) # abs(-5) + abs(6) + abs(9) = 20; 1 was filtered out.\n\nRead this overview section for a quick tutorial of L, as well as background on the name.\nYou can create an L from an existing iterable (e.g. a list, range, etc) and access or modify it with an int list/tuple index, mask, int, or slice. All list methods can also be used with L.\n\nt = L(range(12))\ntest_eq(t, list(range(12)))\ntest_ne(t, list(range(11)))\nt.reverse()\ntest_eq(t[0], 11)\nt[3] = \"h\"\ntest_eq(t[3], \"h\")\nt[3,5] = (\"j\",\"k\")\ntest_eq(t[3,5], [\"j\",\"k\"])\ntest_eq(t, L(t))\ntest_eq(L(L(1,2),[3,4]), ([1,2],[3,4]))\nt\n\n(#12) [11,10,9,'j',7,'k',5,4,3,2...]\n\n\nAny L is a Sequence so you can use it with methods like random.sample:\n\nassert isinstance(t, Sequence)\n\n\nimport random\n\n\nrandom.seed(0)\nrandom.sample(t, 3)\n\n[5, 0, 11]\n\n\nThere are optimized indexers for arrays, tensors, and DataFrames.\n\nimport pandas as pd\n\n\narr = np.arange(9).reshape(3,3)\nt = L(arr, use_list=None)\ntest_eq(t[1,2], arr[[1,2]])\n\ndf = pd.DataFrame({'a':[1,2,3]})\nt = L(df, use_list=None)\ntest_eq(t[1,2], L(pd.DataFrame({'a':[2,3]}, index=[1,2]), use_list=None))\n\nYou can also modify an L with append, +, and *.\n\nt = L()\ntest_eq(t, [])\nt.append(1)\ntest_eq(t, [1])\nt += [3,2]\ntest_eq(t, [1,3,2])\nt = t + [4]\ntest_eq(t, [1,3,2,4])\nt = 5 + t\ntest_eq(t, [5,1,3,2,4])\ntest_eq(L(1,2,3), [1,2,3])\ntest_eq(L(1,2,3), L(1,2,3))\nt = L(1)*5\nt = t.map(operator.neg)\ntest_eq(t,[-1]*5)\ntest_eq(~L([True,False,False]), L([False,True,True]))\nt = L(range(4))\ntest_eq(zip(t, L(1).cycle()), zip(range(4),(1,1,1,1)))\nt = L.range(100)\ntest_shuffled(t,t.shuffle())\n\n\ntest_eq(L([]).sum(), 0)\ntest_eq(L([]).product(), 1)\n\n\ndef _f(x,a=0): return x+a\nt = L(1)*5\ntest_eq(t.map(_f), t)\ntest_eq(t.map(_f,1), [2]*5)\ntest_eq(t.map(_f,a=2), [3]*5)\n\nAn L can be constructed from anything iterable, although tensors and arrays will not be iterated over on construction, unless you pass use_list to the constructor.\n\ntest_eq(L([1,2,3]),[1,2,3])\ntest_eq(L(L([1,2,3])),[1,2,3])\ntest_ne(L([1,2,3]),[1,2,])\ntest_eq(L('abc'),['abc'])\ntest_eq(L(range(0,3)),[0,1,2])\ntest_eq(L(o for o in range(0,3)),[0,1,2])\ntest_eq(L(array(0)),[array(0)])\ntest_eq(L([array(0),array(1)]),[array(0),array(1)])\ntest_eq(L(array([0.,1.1]))[0],array([0.,1.1]))\ntest_eq(L(array([0.,1.1]), use_list=True), [array(0.),array(1.1)]) # `use_list=True` to unwrap arrays/arrays\n\nIf match is not None then the created list is same len as match, either by:\n\nIf len(items)==1 then items is replicated,\nOtherwise an error is raised if match and items are not already the same size.\n\n\ntest_eq(L(1,match=[1,2,3]),[1,1,1])\ntest_eq(L([1,2],match=[2,3]),[1,2])\ntest_fail(lambda: L([1,2],match=[1,2,3]))\n\nIf you create an L from an existing L then you’ll get back the original object (since L uses the NewChkMeta metaclass).\n\ntest_is(L(t), t)\n\nAn L is considred equal to a list if they have the same elements. It’s never considered equal to a str a set or a dict even if they have the same elements/keys.\n\ntest_eq(L(['a', 'b']), ['a', 'b'])\ntest_ne(L(['a', 'b']), 'ab')\ntest_ne(L(['a', 'b']), {'a':1, 'b':2})\n\n\n\nL Methods\n\nsource\n\n\nL.__getitem__\n\n L.__getitem__ (idx)\n\nRetrieve idx (can be list of indices, or mask, or int) items\n\nt = L(range(12))\ntest_eq(t[1,2], [1,2]) # implicit tuple\ntest_eq(t[[1,2]], [1,2]) # list\ntest_eq(t[:3], [0,1,2]) # slice\ntest_eq(t[[False]*11 + [True]], [11]) # mask\ntest_eq(t[array(3)], 3)\n\n\nsource\n\n\nL.__setitem__\n\n L.__setitem__ (idx, o)\n\nSet idx (can be list of indices, or mask, or int) items to o (which is broadcast if not iterable)\n\nt[4,6] = 0\ntest_eq(t[4,6], [0,0])\nt[4,6] = [1,2]\ntest_eq(t[4,6], [1,2])\n\n\nsource\n\n\nL.unique\n\n L.unique (sort=False, bidir=False, start=None)\n\nUnique items, in stable order\n\ntest_eq(L(4,1,2,3,4,4).unique(), [4,1,2,3])\n\n\nsource\n\n\nL.val2idx\n\n L.val2idx ()\n\nDict from value to index\n\ntest_eq(L(1,2,3).val2idx(), {3:2,1:0,2:1})\n\n\nsource\n\n\nL.filter\n\n L.filter (f=<function noop>, negate=False, **kwargs)\n\nCreate new L filtered by predicate f, passing args and kwargs to f\n\nlist(t)\n\n[0, 1, 2, 3, 1, 5, 2, 7, 8, 9, 10, 11]\n\n\n\ntest_eq(t.filter(lambda o:o<5), [0,1,2,3,1,2])\ntest_eq(t.filter(lambda o:o<5, negate=True), [5,7,8,9,10,11])\n\n\nsource\n\n\nL.argwhere\n\n L.argwhere (f, negate=False, **kwargs)\n\nLike filter, but return indices for matching items\n\ntest_eq(t.argwhere(lambda o:o<5), [0,1,2,3,4,6])\n\n\nsource\n\n\nL.argfirst\n\n L.argfirst (f, negate=False)\n\nReturn index of first matching item\n\ntest_eq(t.argfirst(lambda o:o>4), 5)\ntest_eq(t.argfirst(lambda o:o>4,negate=True),0)\n\n\nsource\n\n\nL.map\n\n L.map (f, *args, **kwargs)\n\nCreate new L with f applied to all items, passing args and kwargs to f\n\ntest_eq(L.range(4).map(operator.neg), [0,-1,-2,-3])\n\nIf f is a string then it is treated as a format string to create the mapping:\n\ntest_eq(L.range(4).map('#{}#'), ['#0#','#1#','#2#','#3#'])\n\nIf f is a dictionary (or anything supporting __getitem__) then it is indexed to create the mapping:\n\ntest_eq(L.range(4).map(list('abcd')), list('abcd'))\n\nYou can also pass the same arg params that bind accepts:\n\ndef f(a=None,b=None): return b\ntest_eq(L.range(4).map(f, b=arg0), range(4))\n\n\nsource\n\n\nL.map_dict\n\n L.map_dict (f=<function noop>, *args, **kwargs)\n\nLike map, but creates a dict from items to function results\n\ntest_eq(L(range(1,5)).map_dict(), {1:1, 2:2, 3:3, 4:4})\ntest_eq(L(range(1,5)).map_dict(operator.neg), {1:-1, 2:-2, 3:-3, 4:-4})\n\n\nsource\n\n\nL.zip\n\n L.zip (cycled=False)\n\nCreate new L with zip(*items)\n\nt = L([[1,2,3],'abc'])\ntest_eq(t.zip(), [(1, 'a'),(2, 'b'),(3, 'c')])\n\n\nt = L([[1,2,3,4],['a','b','c']])\ntest_eq(t.zip(cycled=True ), [(1, 'a'),(2, 'b'),(3, 'c'),(4, 'a')])\ntest_eq(t.zip(cycled=False), [(1, 'a'),(2, 'b'),(3, 'c')])\n\n\nsource\n\n\nL.map_zip\n\n L.map_zip (f, *args, cycled=False, **kwargs)\n\nCombine zip and starmap\n\nt = L([1,2,3],[2,3,4])\ntest_eq(t.map_zip(operator.mul), [2,6,12])\n\n\nsource\n\n\nL.zipwith\n\n L.zipwith (*rest, cycled=False)\n\nCreate new L with self zip with each of *rest\n\nb = [[0],[1],[2,2]]\nt = L([1,2,3]).zipwith(b)\ntest_eq(t, [(1,[0]), (2,[1]), (3,[2,2])])\n\n\nsource\n\n\nL.map_zipwith\n\n L.map_zipwith (f, *rest, cycled=False, **kwargs)\n\nCombine zipwith and starmap\n\ntest_eq(L(1,2,3).map_zipwith(operator.mul, [2,3,4]), [2,6,12])\n\n\nsource\n\n\nL.itemgot\n\n L.itemgot (*idxs)\n\nCreate new L with item idx of all items\n\ntest_eq(t.itemgot(1), b)\n\n\nsource\n\n\nL.attrgot\n\n L.attrgot (k, default=None)\n\nCreate new L with attr k (or value k for dicts) of all items.\n\n# Example when items are not a dict\na = [SimpleNamespace(a=3,b=4),SimpleNamespace(a=1,b=2)]\ntest_eq(L(a).attrgot('b'), [4,2])\n\n#Example of when items are a dict\nb =[{'id': 15, 'name': 'nbdev'}, {'id': 17, 'name': 'fastcore'}]\ntest_eq(L(b).attrgot('id'), [15, 17])\n\n\nsource\n\n\nL.sorted\n\n L.sorted (key=None, reverse=False)\n\nNew L sorted by key. If key is str use attrgetter; if int use itemgetter\n\ntest_eq(L(a).sorted('a').attrgot('b'), [2,4])\n\n\nsource\n\n\nL.split\n\n L.split (s, sep=None, maxsplit=-1)\n\nClass Method: Same as str.split, but returns an L\n\ntest_eq(L.split('a b c'), list('abc'))\n\n\nsource\n\n\nL.range\n\n L.range (a, b=None, step=None)\n\nClass Method: Same as range, but returns L. Can pass collection for a, to use len(a)\n\ntest_eq_type(L.range([1,1,1]), L(range(3)))\ntest_eq_type(L.range(5,2,2), L(range(5,2,2)))\n\n\nsource\n\n\nL.concat\n\n L.concat ()\n\nConcatenate all elements of list\n\ntest_eq(L([0,1,2,3],4,L(5,6)).concat(), range(7))\n\n\nsource\n\n\nL.copy\n\n L.copy ()\n\nSame as list.copy, but returns an L\n\nt = L([0,1,2,3],4,L(5,6)).copy()\ntest_eq(t.concat(), range(7))\n\n\nsource\n\n\nL.map_first\n\n L.map_first (f=<function noop>, g=<function noop>, *args, **kwargs)\n\nFirst element of map_filter\n\nt = L(0,1,2,3)\ntest_eq(t.map_first(lambda o:o*2 if o>2 else None), 6)\n\n\nsource\n\n\nL.setattrs\n\n L.setattrs (attr, val)\n\nCall setattr on all items\n\nt = L(SimpleNamespace(),SimpleNamespace())\nt.setattrs('foo', 'bar')\ntest_eq(t.attrgot('foo'), ['bar','bar'])", + "crumbs": [ + "Foundation" + ] + }, + { + "objectID": "foundation.html#config", + "href": "foundation.html#config", + "title": "Foundation", + "section": "Config", + "text": "Config\n\nsource\n\nsave_config_file\n\n save_config_file (file, d, **kwargs)\n\nWrite settings dict to a new config file, or overwrite the existing one.\n\nsource\n\n\nread_config_file\n\n read_config_file (file, **kwargs)\n\nConfig files are saved and read using Python’s configparser.ConfigParser, inside the DEFAULT section.\n\n_d = dict(user='fastai', lib_name='fastcore', some_path='test', some_bool=True, some_num=3)\ntry:\n save_config_file('tmp.ini', _d)\n res = read_config_file('tmp.ini')\nfinally: os.unlink('tmp.ini')\ndict(res)\n\n{'user': 'fastai',\n 'lib_name': 'fastcore',\n 'some_path': 'test',\n 'some_bool': 'True',\n 'some_num': '3'}\n\n\n\nsource\n\n\nConfig\n\n Config (cfg_path, cfg_name, create=None, save=True, extra_files=None,\n types=None)\n\nReading and writing ConfigParser ini files\nConfig is a convenient wrapper around ConfigParser ini files with a single section (DEFAULT).\nInstantiate a Config from an ini file at cfg_path/cfg_name:\n\nsave_config_file('../tmp.ini', _d)\ntry: cfg = Config('..', 'tmp.ini')\nfinally: os.unlink('../tmp.ini')\ncfg\n\n{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test', 'some_bool': 'True', 'some_num': '3'}\n\n\nYou can create a new file if one doesn’t exist by providing a create dict:\n\ntry: cfg = Config('..', 'tmp.ini', create=_d)\nfinally: os.unlink('../tmp.ini')\ncfg\n\n{'user': 'fastai', 'lib_name': 'fastcore', 'some_path': 'test', 'some_bool': 'True', 'some_num': '3'}\n\n\nIf you additionally pass save=False, the Config will contain the items from create without writing a new file:\n\ncfg = Config('..', 'tmp.ini', create=_d, save=False)\ntest_eq(cfg.user,'fastai')\nassert not Path('../tmp.ini').exists()\n\nKeys can be accessed as attributes, items, or with get and an optional default:\n\ntest_eq(cfg.user,'fastai')\ntest_eq(cfg['some_path'], 'test')\ntest_eq(cfg.get('foo','bar'),'bar')\n\nExtra files can be read before cfg_path/cfg_name using extra_files, in the order they appear:\n\nwith tempfile.TemporaryDirectory() as d:\n a = Config(d, 'a.ini', {'a':0,'b':0})\n b = Config(d, 'b.ini', {'a':1,'c':0})\n c = Config(d, 'c.ini', {'a':2,'d':0}, extra_files=[a.config_file,b.config_file])\n test_eq(c.d, {'a':'2','b':'0','c':'0','d':'0'})\n\nIf you pass a dict types, then the values of that dict will be used as types to instantiate all values returned. Path is a special case – in that case, the path returned will be relative to the path containing the config file (assuming the value is relative). bool types use str2bool to convert to boolean.\n\n_types = dict(some_path=Path, some_bool=bool, some_num=int)\ncfg = Config('..', 'tmp.ini', create=_d, save=False, types=_types)\n\ntest_eq(cfg.user,'fastai')\ntest_eq(cfg['some_path'].resolve(), (Path('..')/'test').resolve())\ntest_eq(cfg.get('some_num'), 3)", + "crumbs": [ + "Foundation" + ] + }, + { + "objectID": "py2pyi.html#basics", + "href": "py2pyi.html#basics", + "title": "Create delegated pyi", + "section": "Basics", + "text": "Basics\n\nsource\n\nimp_mod\n\n imp_mod (module_path, package=None)\n\nImport dynamically the module referenced in fn\n\nfn = Path('test_py2pyi.py')\n\n\nmod = imp_mod(fn)\na = mod.A()\na.h()\n\n1\n\n\n\ntree = _get_tree(mod)\n\n\n\n\nAST.__repr__\n\n AST.__repr__ ()\n\n\n# for o in enumerate(tree.body): print(o)\n\n\nnode = tree.body[4]\nnode\n\ndef f(a: int, b: str='a') -> str:\n \"\"\"I am f\"\"\"\n return 1\n\n\n\nisinstance(node, functypes)\n\nTrue\n\n\n\nsource\n\n\nhas_deco\n\n has_deco (node:Union[ast.FunctionDef,ast.AsyncFunctionDef], name:str)\n\nCheck if a function node node has a decorator named name\n\nnm = 'delegates'\nhas_deco(node, nm)\n\nFalse\n\n\n\nnode = tree.body[5]\nnode\n\n@delegates(f)\ndef g(c, d: X, **kwargs) -> str:\n \"\"\"I am g\"\"\"\n return 2\n\n\n\nhas_deco(node, nm)\n\nTrue", + "crumbs": [ + "Create delegated pyi" + ] + }, + { + "objectID": "py2pyi.html#function-processing", + "href": "py2pyi.html#function-processing", + "title": "Create delegated pyi", + "section": "Function processing", + "text": "Function processing\n\ndef _proc_body (node, mod): print('_proc_body', type(node))\ndef _proc_func (node, mod): print('_proc_func', type(node))\ndef _proc_class (node, mod): print('_proc_class', type(node))\ndef _proc_patched(node, mod): print('_proc_patched', type(node))\n\n\n_proc_mod(mod);\n\n_proc_class <class 'ast.ClassDef'>\n_proc_body <class 'ast.FunctionDef'>\n_proc_func <class 'ast.FunctionDef'>\n_proc_body <class 'ast.FunctionDef'>\n_proc_class <class 'ast.ClassDef'>\n_proc_class <class 'ast.ClassDef'>\n_proc_patched <class 'ast.FunctionDef'>\n_proc_patched <class 'ast.FunctionDef'>\n_proc_body <class 'ast.FunctionDef'>\n\n\n\nnode.name\n\n'g'\n\n\n\nsym = getattr(mod, node.name)\nsym\n\n<function test_py2pyi.g(c, d: test_py2pyi.X, *, b: str = 'a') -> str>\n\n\n\nsig = signature(sym)\nprint(sig)\n\n(c, d: test_py2pyi.X, *, b: str = 'a') -> str\n\n\n\nsource\n\nsig2str\n\n sig2str (sig)\n\n\nsource\n\n\nast_args\n\n ast_args (func)\n\n\nnewargs = ast_args(sym)\nnewargs\n\nc, d: test_py2pyi.X, *, b: str='a'\n\n\n\nnode.args\n\nc, d: X, **kwargs\n\n\n\nnode.args = newargs\nnode\n\n@delegates(f)\ndef g(c, d: test_py2pyi.X, *, b: str='a') -> str:\n \"\"\"I am g\"\"\"\n return 2\n\n\n\n_body_ellip(node)\nnode\n\n@delegates(f)\ndef g(c, d: test_py2pyi.X, *, b: str='a') -> str:\n \"\"\"I am g\"\"\"\n ...\n\n\n\ntree = _get_tree(mod)\nnode = tree.body[5]\nnode\n\n@delegates(f)\ndef g(c, d: X, **kwargs) -> str:\n \"\"\"I am g\"\"\"\n return 2\n\n\n\n_update_func(node, sym)\nnode\n\ndef g(c, d: test_py2pyi.X, *, b: str='a') -> str:\n \"\"\"I am g\"\"\"\n ...\n\n\n\ntree = _proc_mod(mod)\ntree.body[5]\n\n_proc_class <class 'ast.ClassDef'>\n_proc_class <class 'ast.ClassDef'>\n_proc_class <class 'ast.ClassDef'>\n_proc_patched <class 'ast.FunctionDef'>\n_proc_patched <class 'ast.FunctionDef'>\n\n\ndef g(c, d: test_py2pyi.X, *, b: str='a') -> str:\n \"\"\"I am g\"\"\"\n ...", + "crumbs": [ + "Create delegated pyi" + ] + }, + { + "objectID": "py2pyi.html#patch", + "href": "py2pyi.html#patch", + "title": "Create delegated pyi", + "section": "Patch", + "text": "Patch\n\nnode = tree.body[9]\nnode\n\n@patch\n@delegates(j)\ndef k(self: (A, B), b: bool=False, **kwargs):\n return 1\n\n\n\nann = node.args.args[0].annotation\n\n\nif hasattr(ann, 'elts'): ann = ann.elts[0]\n\n\nnm = ann.id\nnm\n\n'A'\n\n\n\ncls = getattr(mod, nm)\nsym = getattr(cls, node.name)\n\n\nsig2str(signature(sym))\n\n\"(self: (test_py2pyi.A, test_py2pyi.B), b: bool = False, *, d: str = 'a')\"\n\n\n\n_update_func(node, sym)\n\n\nnode\n\n@patch\ndef k(self: (test_py2pyi.A, test_py2pyi.B), b: bool=False, *, d: str='a'):\n ...\n\n\n\ntree = _proc_mod(mod)\ntree.body[9]\n\n_proc_class <class 'ast.ClassDef'>\n_proc_class <class 'ast.ClassDef'>\n_proc_class <class 'ast.ClassDef'>\n\n\n@patch\ndef k(self: (test_py2pyi.A, test_py2pyi.B), b: bool=False, *, d: str='a'):\n ...", + "crumbs": [ + "Create delegated pyi" + ] + }, + { + "objectID": "py2pyi.html#class-and-file", + "href": "py2pyi.html#class-and-file", + "title": "Create delegated pyi", + "section": "Class and file", + "text": "Class and file\n\ntree = _get_tree(mod)\nnode = tree.body[7]\nnode\n\nclass A:\n\n @delegates(j)\n def h(self, b: bool=False, **kwargs):\n a = 1\n return a\n\n\n\nnode.body\n\n[@delegates(j)\n def h(self, b: bool=False, **kwargs):\n a = 1\n return a]\n\n\n\ntree = _proc_mod(mod)\ntree.body[7]\n\nclass A:\n\n def h(self, b: bool=False, *, d: str='a'):\n ...\n\n\n\nsource\n\ncreate_pyi\n\n create_pyi (fn, package=None)\n\nConvert fname.py to fname.pyi by removing function bodies and expanding delegates kwargs\n\ncreate_pyi(fn)\n\n\n# fn = Path('/Users/jhoward/git/fastcore/fastcore/docments.py')\n# create_pyi(fn, 'fastcore')", + "crumbs": [ + "Create delegated pyi" + ] + }, + { + "objectID": "py2pyi.html#script", + "href": "py2pyi.html#script", + "title": "Create delegated pyi", + "section": "Script", + "text": "Script\n\nsource\n\npy2pyi\n\n py2pyi (fname:str, package:str=None)\n\nConvert fname.py to fname.pyi by removing function bodies and expanding delegates kwargs\n\n\n\n\nType\nDefault\nDetails\n\n\n\n\nfname\nstr\n\nThe file name to convert\n\n\npackage\nstr\nNone\nThe parent package\n\n\n\n\nsource\n\n\nreplace_wildcards\n\n replace_wildcards (path:str)\n\nExpand wildcard imports in the specified Python file.\n\n\n\n\nType\nDetails\n\n\n\n\npath\nstr\nPath to the Python file to process", + "crumbs": [ + "Create delegated pyi" + ] + }, + { + "objectID": "dispatch.html", + "href": "dispatch.html", + "title": "Type dispatch", + "section": "", + "text": "from nbdev.showdoc import *\nfrom fastcore.test import *\nfrom fastcore.nb_imports import *", + "crumbs": [ + "Type dispatch" + ] + }, + { + "objectID": "dispatch.html#helpers", + "href": "dispatch.html#helpers", + "title": "Type dispatch", + "section": "Helpers", + "text": "Helpers\n\nsource\n\nlenient_issubclass\n\n lenient_issubclass (cls, types)\n\nIf possible return whether cls is a subclass of types, otherwise return False.\n\nassert not lenient_issubclass(typing.Collection, list)\nassert lenient_issubclass(list, typing.Collection)\nassert lenient_issubclass(typing.Collection, object)\nassert lenient_issubclass(typing.List, typing.Collection)\nassert not lenient_issubclass(typing.Collection, typing.List)\nassert not lenient_issubclass(object, typing.Callable)\n\n\nsource\n\n\nsorted_topologically\n\n sorted_topologically (iterable, cmp=<built-in function lt>,\n reverse=False)\n\nReturn a new list containing all items from the iterable sorted topologically\n\ntd = [3, 1, 2, 5]\ntest_eq(sorted_topologically(td), [1, 2, 3, 5])\ntest_eq(sorted_topologically(td, reverse=True), [5, 3, 2, 1])\n\n\ntd = {int:1, numbers.Number:2, numbers.Integral:3}\ntest_eq(sorted_topologically(td, cmp=lenient_issubclass), [int, numbers.Integral, numbers.Number])\n\n\ntd = [numbers.Integral, tuple, list, int, dict]\ntd = sorted_topologically(td, cmp=lenient_issubclass)\nassert td.index(int) < td.index(numbers.Integral)", + "crumbs": [ + "Type dispatch" + ] + }, + { + "objectID": "dispatch.html#typedispatch", + "href": "dispatch.html#typedispatch", + "title": "Type dispatch", + "section": "TypeDispatch", + "text": "TypeDispatch\nType dispatch, or Multiple dispatch, allows you to change the way a function behaves based upon the input types it recevies. This is a prominent feature in some programming languages like Julia. For example, this is a conceptual example of how multiple dispatch works in Julia, returning different values depending on the input types of x and y:\ncollide_with(x::Asteroid, y::Asteroid) = ... \n# deal with asteroid hitting asteroid\n\ncollide_with(x::Asteroid, y::Spaceship) = ... \n# deal with asteroid hitting spaceship\n\ncollide_with(x::Spaceship, y::Asteroid) = ... \n# deal with spaceship hitting asteroid\n\ncollide_with(x::Spaceship, y::Spaceship) = ... \n# deal with spaceship hitting spaceship\nType dispatch can be especially useful in data science, where you might allow different input types (i.e. numpy arrays and pandas dataframes) to function that processes data. Type dispatch allows you to have a common API for functions that do similar tasks.\nThe TypeDispatch class allows us to achieve type dispatch in Python. It contains a dictionary that maps types from type annotations to functions, which ensures that the proper function is called when passed inputs.\n\nsource\n\nTypeDispatch\n\n TypeDispatch (funcs=(), bases=())\n\nDictionary-like object; __getitem__ matches keys of types using issubclass\nTo demonstrate how TypeDispatch works, we define a set of functions that accept a variety of input types, specified with different type annotations:\n\ndef f2(x:int, y:float): return x+y #int and float for 2nd arg\ndef f_nin(x:numbers.Integral)->int: return x+1 #integral numeric\ndef f_ni2(x:int): return x #integer\ndef f_bll(x:bool|list): return x #bool or list\ndef f_num(x:numbers.Number): return x #Number (root of numerics)\n\nWe can optionally initialize TypeDispatch with a list of functions we want to search. Printing an instance of TypeDispatch will display convenient mapping of types -> functions:\n\nt = TypeDispatch([f_nin,f_ni2,f_num,f_bll,None])\nt\n\n(bool,object) -> f_bll\n(int,object) -> f_ni2\n(Integral,object) -> f_nin\n(Number,object) -> f_num\n(list,object) -> f_bll\n(object,object) -> NoneType\n\n\nNote that only the first two arguments are used for TypeDispatch. If your function only contains one argument, the second parameter will be shown as object. If you pass None into TypeDispatch, then this will be displayed as (object, object) -> NoneType.\nTypeDispatch is a dictionary-like object, which means that you can retrieve a function by the associated type annotation. For example, the statement:\nt[float]\nWill return f_num because that is the matching function that has a type annotation that is a super-class of of float - numbers.Number:\n\nassert issubclass(float, numbers.Number)\ntest_eq(t[float], f_num)\n\nThe same is true for other types as well:\n\ntest_eq(t[np.int32], f_nin)\ntest_eq(t[bool], f_bll)\ntest_eq(t[list], f_bll)\ntest_eq(t[np.int32], f_nin)\n\nIf you try to get a type that doesn’t match, TypeDispatch will return None:\n\ntest_eq(t[str], None)\n\n\nsource\n\n\nTypeDispatch.add\n\n TypeDispatch.add (f)\n\nAdd type t and function f\nThis method allows you to add an additional function to an existing TypeDispatch instance :\n\ndef f_col(x:typing.Collection): return x\nt.add(f_col)\ntest_eq(t[str], f_col)\nt\n\n(bool,object) -> f_bll\n(int,object) -> f_ni2\n(Integral,object) -> f_nin\n(Number,object) -> f_num\n(list,object) -> f_bll\n(typing.Collection,object) -> f_col\n(object,object) -> NoneType\n\n\nIf you accidentally add the same function more than once things will still work as expected:\n\nt.add(f_ni2) \ntest_eq(t[int], f_ni2)\n\nHowever, if you add a function that has a type collision that raises an ambiguity, this will automatically resolve to the latest function added:\n\ndef f_ni3(z:int): return z # collides with f_ni2 with same type annotations\nt.add(f_ni3) \ntest_eq(t[int], f_ni3)\n\n\nUsing bases:\nThe argument bases can optionally accept a single instance of TypeDispatch or a collection (i.e. a tuple or list) of TypeDispatch objects. This can provide functionality similar to multiple inheritance.\nThese are searched for matching functions if no match in your list of functions:\n\ndef f_str(x:str): return x+'1'\n\nt = TypeDispatch([f_nin,f_ni2,f_num,f_bll,None])\nt2 = TypeDispatch(f_str, bases=t) # you can optionally supply a list of TypeDispatch objects for `bases`.\nt2\n\n(str,object) -> f_str\n(bool,object) -> f_bll\n(int,object) -> f_ni2\n(Integral,object) -> f_nin\n(Number,object) -> f_num\n(list,object) -> f_bll\n(object,object) -> NoneType\n\n\n\ntest_eq(t2[int], f_ni2) # searches `t` b/c not found in `t2`\ntest_eq(t2[np.int32], f_nin) # searches `t` b/c not found in `t2`\ntest_eq(t2[float], f_num) # searches `t` b/c not found in `t2`\ntest_eq(t2[bool], f_bll) # searches `t` b/c not found in `t2`\ntest_eq(t2[str], f_str) # found in `t`!\ntest_eq(t2('a'), 'a1') # found in `t`!, and uses __call__\n\no = np.int32(1)\ntest_eq(t2(o), 2) # found in `t2` and uses __call__\n\n\n\nUp To Two Arguments\nTypeDispatch supports up to two arguments when searching for the appropriate function. The following functions f1 and f2 both have two parameters:\n\ndef f1(x:numbers.Integral, y): return x+1 #Integral is a numeric type\ndef f2(x:int, y:float): return x+y\nt = TypeDispatch([f1,f2])\nt\n\n(int,float) -> f2\n(Integral,object) -> f1\n\n\nYou can lookup functions from a TypeDispatch instance with two parameters like this:\n\ntest_eq(t[np.int32], f1)\ntest_eq(t[int,float], f2)\n\nKeep in mind that anything beyond the first two parameters are ignored, and any collisions will be resolved in favor of the most recent function added. In the below example, f1 is ignored in favor of f2 because the first two parameters have identical type hints:\n\ndef f1(a:str, b:int, c:list): return a\ndef f2(a: str, b:int): return b\nt = TypeDispatch([f1,f2])\ntest_eq(t[str, int], f2)\nt\n\n(str,int) -> f2\n\n\n\n\nMatching\nType Dispatch matches types with functions according to whether the supplied class is a subclass or the same class of the type annotation(s) of associated functions.\nLet’s consider an example where we try to retrieve the function corresponding to types of [np.int32, float].\nIn this scenario, f2 will not be matched. This is because the first type annotation of f2, int, is not a superclass (or the same class) of np.int32:\n\ndef f1(x:numbers.Integral, y): return x+1\ndef f2(x:int, y:float): return x+y\nt = TypeDispatch([f1,f2])\n\nassert not issubclass(np.int32, int)\n\nInstead, f1 is a valid match, as its first argument is annoted with the type numbers.Integeral, which np.int32 is a subclass of:\n\nassert issubclass(np.int32, numbers.Integral)\ntest_eq(t[np.int32,float], f1)\n\nIn f1 , the 2nd parameter y is not annotated, which means TypeDispatch will match anything where the first argument matches int that is not matched with anything else:\n\nassert issubclass(int, numbers.Integral) # int is a subclass of numbers.Integral\ntest_eq(t[int], f1)\ntest_eq(t[int,int], f1)\n\nIf no match is possible, None is returned:\n\ntest_eq(t[float,float], None)\n\n\nsource\n\n\n\nTypeDispatch.__call__\n\n TypeDispatch.__call__ (*args, **kwargs)\n\nCall self as a function.\nTypeDispatch is also callable. When you call an instance of TypeDispatch, it will execute the relevant function:\n\ndef f_arr(x:np.ndarray): return x.sum()\ndef f_int(x:np.int32): return x+1\nt = TypeDispatch([f_arr, f_int])\n\narr = np.array([5,4,3,2,1])\ntest_eq(t(arr), 15) # dispatches to f_arr\n\no = np.int32(1)\ntest_eq(t(o), 2) # dispatches to f_int\nassert t.first() is not None\n\nYou can also call an instance of of TypeDispatch when there are two parameters:\n\ndef f1(x:numbers.Integral, y): return x+1\ndef f2(x:int, y:float): return x+y\nt = TypeDispatch([f1,f2])\n\ntest_eq(t(3,2.0), 5)\ntest_eq(t(3,2), 4)\n\nWhen no match is found, a TypeDispatch instance becomes an identity function. This default behavior is leveraged by fasatai for data transformations to provide a sensible default when a matching function cannot be found.\n\ntest_eq(t('a'), 'a')\n\n\nsource\n\n\nTypeDispatch.returns\n\n TypeDispatch.returns (x)\n\nGet the return type of annotation of x.\nYou can optionally pass an object to TypeDispatch.returns and get the return type annotation back:\n\ndef f1(x:int) -> np.ndarray: return np.array(x)\ndef f2(x:str) -> float: return List\ndef f3(x:float): return List # f3 has no return type annotation\n\nt = TypeDispatch([f1, f2, f3])\n\ntest_eq(t.returns(1), np.ndarray) # dispatched to f1\ntest_eq(t.returns('Hello'), float) # dispatched to f2\ntest_eq(t.returns(1.0), None) # dispatched to f3\n\nclass _Test: pass\n_test = _Test()\ntest_eq(t.returns(_test), None) # type `_Test` not found, so None returned\n\n\nUsing TypeDispatch With Methods\nYou can use TypeDispatch when defining methods as well:\n\ndef m_nin(self, x:str|numbers.Integral): return str(x)+'1'\ndef m_bll(self, x:bool): self.foo='a'\ndef m_num(self, x:numbers.Number): return x*2\n\nt = TypeDispatch([m_nin,m_num,m_bll])\nclass A: f = t # set class attribute `f` equal to a TypeDispatch instance\n \na = A()\ntest_eq(a.f(1), '11') #dispatch to m_nin\ntest_eq(a.f(1.), 2.) #dispatch to m_num\ntest_is(a.f.inst, a)\n\na.f(False) # this triggers t.m_bll to run, which sets self.foo to 'a'\ntest_eq(a.foo, 'a')\n\nAs discussed in TypeDispatch.__call__, when there is not a match, TypeDispatch.__call__ becomes an identity function. In the below example, a tuple does not match any type annotations so a tuple is returned:\n\ntest_eq(a.f(()), ())\n\nWe extend the previous example by using bases to add an additional method that supports tuples:\n\ndef m_tup(self, x:tuple): return x+(1,)\nt2 = TypeDispatch(m_tup, bases=t)\n\nclass A2: f = t2\na2 = A2()\ntest_eq(a2.f(1), '11')\ntest_eq(a2.f(1.), 2.)\ntest_is(a2.f.inst, a2)\na2.f(False)\ntest_eq(a2.foo, 'a')\ntest_eq(a2.f(()), (1,))\n\n\n\nUsing TypeDispatch With Class Methods\nYou can use TypeDispatch when defining class methods too:\n\ndef m_nin(cls, x:str|numbers.Integral): return str(x)+'1'\ndef m_bll(cls, x:bool): cls.foo='a'\ndef m_num(cls, x:numbers.Number): return x*2\n\nt = TypeDispatch([m_nin,m_num,m_bll])\nclass A: f = t # set class attribute `f` equal to a TypeDispatch\n\ntest_eq(A.f(1), '11') #dispatch to m_nin\ntest_eq(A.f(1.), 2.) #dispatch to m_num\ntest_is(A.f.owner, A)\n\nA.f(False) # this triggers t.m_bll to run, which sets A.foo to 'a'\ntest_eq(A.foo, 'a')", + "crumbs": [ + "Type dispatch" + ] + }, + { + "objectID": "dispatch.html#typedispatch-decorator", + "href": "dispatch.html#typedispatch-decorator", + "title": "Type dispatch", + "section": "typedispatch Decorator", + "text": "typedispatch Decorator\n\nsource\n\nDispatchReg\n\n DispatchReg ()\n\nA global registry for TypeDispatch objects keyed by function name\n\n@typedispatch\ndef f_td_test(x, y): return f'{x}{y}'\n@typedispatch\ndef f_td_test(x:numbers.Integral|int, y): return x+1\n@typedispatch\ndef f_td_test(x:int, y:float): return x+y\n@typedispatch\ndef f_td_test(x:int, y:int): return x*y\n\ntest_eq(f_td_test(3,2.0), 5)\nassert issubclass(int, numbers.Integral)\ntest_eq(f_td_test(3,2), 6)\n\ntest_eq(f_td_test('a','b'), 'ab')\n\n\nUsing typedispatch With other decorators\nYou can use typedispatch with classmethod and staticmethod decorator\n\nclass A:\n @typedispatch\n def f_td_test(self, x:numbers.Integral, y): return x+1\n @typedispatch\n @classmethod\n def f_td_test(cls, x:int, y:float): return x+y\n @typedispatch\n @staticmethod\n def f_td_test(x:int, y:int): return x*y\n \ntest_eq(A.f_td_test(3,2), 6)\ntest_eq(A.f_td_test(3,2.0), 5)\ntest_eq(A().f_td_test(3,'2.0'), 4)", + "crumbs": [ + "Type dispatch" + ] + }, + { + "objectID": "dispatch.html#casting", + "href": "dispatch.html#casting", + "title": "Type dispatch", + "section": "Casting", + "text": "Casting\nNow that we can dispatch on types, let’s make it easier to cast objects to a different type.\n\nsource\n\nretain_meta\n\n retain_meta (x, res, as_copy=False)\n\nCall res.set_meta(x), if it exists\n\nsource\n\n\ndefault_set_meta\n\n default_set_meta (x, as_copy=False)\n\nCopy over _meta from x to res, if it’s missing\n\n\n\n(object,object) -> cast\nDictionary-like object; __getitem__ matches keys of types using issubclass\nThis works both for plain python classes:…\n\nmk_class('_T1', 'a') # mk_class is a fastai utility that constructs a class.\nclass _T2(_T1): pass\n\nt = _T1(a=1)\nt2 = cast(t, _T2) \nassert t2 is t # t2 refers to the same object as t\nassert isinstance(t, _T2) # t also changed in-place\nassert isinstance(t2, _T2)\n\ntest_eq_type(_T2(a=1), t2)\n\n…as well as for arrays and tensors.\n\nclass _T1(ndarray): pass\n\nt = array([1])\nt2 = cast(t, _T1)\ntest_eq(array([1]), t2)\ntest_eq(_T1, type(t2))\n\nTo customize casting for other types, define a separate cast function with typedispatch for your type.\n\nsource\n\n\nretain_type\n\n retain_type (new, old=None, typ=None, as_copy=False)\n\nCast new to type of old or typ if it’s a superclass\n\nclass _T(tuple): pass\na = _T((1,2))\nb = tuple((1,2))\nc = retain_type(b, typ=_T)\ntest_eq_type(c, a)\n\nIf old has a _meta attribute, its content is passed when casting new to the type of old. In the below example, only the attribute a, but not other_attr is kept, because other_attr is not in _meta:\n\nclass _A():\n set_meta = default_set_meta\n def __init__(self, t): self.t=t\n\nclass _B1(_A):\n def __init__(self, t, a=1):\n super().__init__(t)\n self._meta = {'a':a}\n self.other_attr = 'Hello' # will not be kept after casting.\n \nx = _B1(1, a=2)\nb = _A(1)\nc = retain_type(b, old=x)\ntest_eq(c._meta, {'a': 2})\nassert not getattr(c, 'other_attr', None)\n\n\nsource\n\n\nretain_types\n\n retain_types (new, old=None, typs=None)\n\nCast each item of new to type of matching item in old if it’s a superclass\n\nclass T(tuple): pass\n\nt1,t2 = retain_types((1,(1,(1,1))), (2,T((2,T((3,4))))))\ntest_eq_type(t1, 1)\ntest_eq_type(t2, T((1,T((1,1)))))\n\nt1,t2 = retain_types((1,(1,(1,1))), typs = {tuple: [int, {T: [int, {T: [int,int]}]}]})\ntest_eq_type(t1, 1)\ntest_eq_type(t2, T((1,T((1,1)))))\n\n\nsource\n\n\nexplode_types\n\n explode_types (o)\n\nReturn the type of o, potentially in nested dictionaries for thing that are listy\n\ntest_eq(explode_types((2,T((2,T((3,4)))))), {tuple: [int, {T: [int, {T: [int,int]}]}]})", + "crumbs": [ + "Type dispatch" + ] + }, + { + "objectID": "index.html", + "href": "index.html", + "title": "Welcome to fastcore", + "section": "", + "text": "Python is a powerful, dynamic language. Rather than bake everything into the language, it lets the programmer customize it to make it work for them. fastcore uses this flexibility to add to Python features inspired by other languages we’ve loved, like multiple dispatch from Julia, mixins from Ruby, and currying, binding, and more from Haskell. It also adds some “missing features” and clean up some rough edges in the Python standard library, such as simplifying parallel processing, and bringing ideas from NumPy over to Python’s list type.", + "crumbs": [ + "Welcome to fastcore" + ] + }, + { + "objectID": "index.html#getting-started", + "href": "index.html#getting-started", + "title": "Welcome to fastcore", + "section": "Getting started", + "text": "Getting started\nTo install fastcore run: conda install fastcore -c fastai (if you use Anaconda, which we recommend) or pip install fastcore. For an editable install, clone this repo and run: pip install -e \".[dev]\". fastcore is tested to work on Ubuntu, macOS and Windows (versions tested are those shown with the -latest suffix here).\nfastcore contains many features, including:\n\nfastcore.test: Simple testing functions\nfastcore.foundation: Mixins, delegation, composition, and more\nfastcore.xtras: Utility functions to help with functional-style programming, parallel processing, and more\nfastcore.dispatch: Multiple dispatch methods\nfastcore.transform: Pipelines of composed partially reversible transformations\n\nTo get started, we recommend you read through the fastcore tour.", + "crumbs": [ + "Welcome to fastcore" + ] + }, + { + "objectID": "index.html#contributing", + "href": "index.html#contributing", + "title": "Welcome to fastcore", + "section": "Contributing", + "text": "Contributing\nAfter you clone this repository, please run nbdev_install_hooks in your terminal. This sets up git hooks, which clean up the notebooks to remove the extraneous stuff stored in the notebooks (e.g. which cells you ran) which causes unnecessary merge conflicts.\nTo run the tests in parallel, launch nbdev_test.\nBefore submitting a PR, check that the local library and notebooks match.\n\nIf you made a change to the notebooks in one of the exported cells, you can export it to the library with nbdev_prepare.\nIf you made a change to the library, you can export it back to the notebooks with nbdev_update.", + "crumbs": [ + "Welcome to fastcore" + ] + }, + { + "objectID": "transform.html", + "href": "transform.html", + "title": "Transforms", + "section": "", + "text": "from __future__ import annotations\nfrom nbdev.showdoc import *\nfrom fastcore.test import *\nfrom fastcore.nb_imports import *\n\nThe classes here provide functionality for creating a composition of partially reversible functions. By “partially reversible” we mean that a transform can be decoded, creating a form suitable for display. This is not necessarily identical to the original form (e.g. a transform that changes a byte tensor to a float tensor does not recreate a byte tensor when decoded, since that may lose precision, and a float tensor can be displayed already).\nClasses are also provided and for composing transforms, and mapping them over collections. Pipeline is a transform which composes several Transform, knowing how to decode them or show an encoded item.\n\nsource\n\nTransform\n\n Transform (enc=None, dec=None, split_idx=None, order=None)\n\nDelegates (__call__,decode,setup) to (encodes,decodes,setups) if split_idx matches\nA Transform is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the Transform class provides several mechanisms that make the process of building them easy and flexible.\n\n\nThe main Transform features:\n\nType dispatch - Type annotations are used to determine if a transform should be applied to the given argument. It also gives an option to provide several implementations and it choses the one to run based on the type. This is useful for example when running both independent and dependent variables through the pipeline where some transforms only make sense for one and not the other. Another usecase is designing a transform that handles different data formats. Note that if a transform takes multiple arguments only the type of the first one is used for dispatch.\nHandling of tuples - When a tuple (or a subclass of tuple) of data is passed to a transform it will get applied to each element separately. You can opt out of this behavior by passing a list or an L, as only tuples gets this specific behavior. An alternative is to use ItemTransform defined below, which will always take the input as a whole.\nReversability - A transform can be made reversible by implementing the decodes method. This is mainly used to turn something like a category which is encoded as a number back into a label understandable by humans for showing purposes. Like the regular call method, the decode method that is used to decode will be applied over each element of a tuple separately.\nType propagation - Whenever possible a transform tries to return data of the same type it received. Mainly used to maintain semantics of things like ArrayImage which is a thin wrapper of pytorch’s Tensor. You can opt out of this behavior by adding ->None return type annotation.\nPreprocessing - The setup method can be used to perform any one-time calculations to be later used by the transform, for example generating a vocabulary to encode categorical data.\nFiltering based on the dataset type - By setting the split_idx flag you can make the transform be used only in a specific DataSource subset like in training, but not validation.\nOrdering - You can set the order attribute which the Pipeline uses when it needs to merge two lists of transforms.\nAppending new behavior with decorators - You can easily extend an existing Transform by creating encodes or decodes methods for new data types. You can put those new methods outside the original transform definition and decorate them with the class you wish them patched into. This can be used by the fastai library users to add their own behavior, or multiple modules contributing to the same transform.\n\n\n\nDefining a Transform\nThere are a few ways to create a transform with different ratios of simplicity to flexibility. - Extending the Transform class - Use inheritence to implement the methods you want. - Passing methods to the constructor - Instantiate the Transform class and pass your functions as enc and dec arguments. - @Transform decorator - Turn any function into a Transform by just adding a decorator - very straightforward if all you need is a single encodes implementation. - Passing a function to fastai APIs - Same as above, but when passing a function to other transform aware classes like Pipeline or TfmdDS you don’t even need a decorator. Your function will get converted to a Transform automatically.\nA simple way to create a Transform is to pass a function to the constructor. In the below example, we pass an anonymous function that does integer division by 2:\n\nf = Transform(lambda o:o//2)\n\nIf you call this transform, it will apply the transformation:\n\ntest_eq_type(f(2), 1)\n\nAnother way to define a Transform is to extend the Transform class:\n\nclass A(Transform): pass\n\nHowever, to enable your transform to do something, you have to define an encodes method. Note that we can use the class name as a decorator to add this method to the original class.\n\n@A\ndef encodes(self, x): return x+1\n\nf1 = A()\ntest_eq(f1(1), 2) # f1(1) is the same as f1.encode(1)\n\nIn addition to adding an encodes method, we can also add a decodes method. This enables you to call the decode method (without an s). For more information about the purpose of decodes, see the discussion about Reversibility in the above section.\nJust like with encodes, you can add a decodes method to the original class by using the class name as a decorator:\n\nclass B(A): pass\n\n@B\ndef decodes(self, x): return x-1\n\nf2 = B()\ntest_eq(f2.decode(2), 1)\n\ntest_eq(f2(1), 2) # uses A's encode method from the parent class\n\nIf you do not define an encodes or decodes method the original value will be returned:\n\nclass _Tst(Transform): pass \n\nf3 = _Tst() # no encodes or decodes method have been defined\ntest_eq_type(f3.decode(2.0), 2.0)\ntest_eq_type(f3(2), 2)\n\nTransforms can be created from class methods too:\n\nclass A:\n @classmethod\n def create(cls, x:int): return x+1\ntest_eq(Transform(A.create)(1), 2)\n\n\nDefining Transforms With A Decorator\nTransform can be used as a decorator to turn a function into a Transform.\n\n@Transform\ndef f(x): return x//2\ntest_eq_type(f(2), 1)\ntest_eq_type(f.decode(2.0), 2.0)\n\n@Transform\ndef f(x): return x*2\ntest_eq_type(f(2), 4)\ntest_eq_type(f.decode(2.0), 2.0)\n\n\n\nTyped Dispatch and Transforms\nWe can also apply different transformations depending on the type of the input passed by using TypedDispatch. TypedDispatch automatically works with Transform when using type hints:\n\nclass A(Transform): pass\n\n@A\ndef encodes(self, x:int): return x//2\n\n@A\ndef encodes(self, x:float): return x+1\n\nWhen we pass in an int, this calls the first encodes method:\n\nf = A()\ntest_eq_type(f(3), 1)\n\nWhen we pass in a float, this calls the second encodes method:\n\ntest_eq_type(f(2.), 3.)\n\nWhen we pass in a type that is not specified in encodes, the original value is returned:\n\ntest_eq(f('a'), 'a')\n\nIf the type annotation is a tuple, then any type in the tuple will match:\n\nclass MyClass(int): pass\n\nclass A(Transform):\n def encodes(self, x:MyClass|float): return x/2\n def encodes(self, x:str|list): return str(x)+'_1'\n\nf = A()\n\nThe below two examples match the first encodes, with a type of MyClass and float, respectively:\n\ntest_eq(f(MyClass(2)), 1.) # input is of type MyClass \ntest_eq(f(6.0), 3.0) # input is of type float\n\nThe next two examples match the second encodes method, with a type of str and list, respectively:\n\ntest_eq(f('a'), 'a_1') # input is of type str\ntest_eq(f(['a','b','c']), \"['a', 'b', 'c']_1\") # input is of type list\n\n\n\nCasting Types With Transform\nWithout any intervention it is easy for operations to change types in Python. For example, FloatSubclass (defined below) becomes a float after performing multiplication:\n\nclass FloatSubclass(float): pass\ntest_eq_type(FloatSubclass(3.0) * 2, 6.0)\n\nThis behavior is often not desirable when performing transformations on data. Therefore, Transform will attempt to cast the output to be of the same type as the input by default. In the below example, the output will be cast to a FloatSubclass type to match the type of the input:\n\n@Transform\ndef f(x): return x*2\n\ntest_eq_type(f(FloatSubclass(3.0)), FloatSubclass(6.0))\n\nWe can optionally turn off casting by annotating the transform function with a return type of None:\n\n@Transform\ndef f(x)-> None: return x*2 # Same transform as above, but with a -> None annotation\n\ntest_eq_type(f(FloatSubclass(3.0)), 6.0) # Casting is turned off because of -> None annotation\n\nHowever, Transform will only cast output back to the input type when the input is a subclass of the output. In the below example, the input is of type FloatSubclass which is not a subclass of the output which is of type str. Therefore, the output doesn’t get cast back to FloatSubclass and stays as type str:\n\n@Transform\ndef f(x): return str(x)\n \ntest_eq_type(f(Float(2.)), '2.0')\n\nJust like encodes, the decodes method will cast outputs to match the input type in the same way. In the below example, the output of decodes remains of type MySubclass:\n\nclass MySubclass(int): pass\n\ndef enc(x): return MySubclass(x+1)\ndef dec(x): return x-1\n\n\nf = Transform(enc,dec)\nt = f(1) # t is of type MySubclass\ntest_eq_type(f.decode(t), MySubclass(1)) # the output of decode is cast to MySubclass to match the input type.\n\n\n\nApply Transforms On Subsets With split_idx\nYou can apply transformations to subsets of data by specifying a split_idx property. If a transform has a split_idx then it’s only applied if the split_idx param matches. In the below example, we set split_idx equal to 1:\n\ndef enc(x): return x+1\ndef dec(x): return x-1\nf = Transform(enc,dec)\nf.split_idx = 1\n\nThe transformations are applied when a matching split_idx parameter is passed:\n\ntest_eq(f(1, split_idx=1),2)\ntest_eq(f.decode(2, split_idx=1),1)\n\nOn the other hand, transformations are ignored when the split_idx parameter does not match:\n\ntest_eq(f(1, split_idx=0), 1)\ntest_eq(f.decode(2, split_idx=0), 2)\n\n\n\nTransforms on Lists\nTransform operates on lists as a whole, not element-wise:\n\nclass A(Transform):\n def encodes(self, x): return dict(x)\n def decodes(self, x): return list(x.items())\n \nf = A()\n_inp = [(1,2), (3,4)]\nt = f(_inp)\n\ntest_eq(t, dict(_inp))\ntest_eq(f.decodes(t), _inp)\n\nIf you want a transform to operate on a list elementwise, you must implement this appropriately in the encodes and decodes methods:\n\nclass AL(Transform): pass\n\n@AL\ndef encodes(self, x): return [x_+1 for x_ in x]\n\n@AL\ndef decodes(self, x): return [x_-1 for x_ in x]\n\nf = AL()\nt = f([1,2])\n\ntest_eq(t, [2,3])\ntest_eq(f.decode(t), [1,2])\n\n\n\nTransforms on Tuples\nUnlike lists, Transform operates on tuples element-wise.\n\ndef neg_int(x): return -x\nf = Transform(neg_int)\n\ntest_eq(f((1,2,3)), (-1,-2,-3))\n\nTransforms will also apply TypedDispatch element-wise on tuples when an input type annotation is specified. In the below example, the values 1.0 and 3.0 are ignored because they are of type float, not int:\n\ndef neg_int(x:int): return -x\nf = Transform(neg_int)\n\ntest_eq(f((1.0, 2, 3.0)), (1.0, -2, 3.0))\n\nAnother example of how Transform can use TypedDispatch with tuples is shown below:\n\nclass B(Transform): pass\n\n@B\ndef encodes(self, x:int): return x+1\n\n@B\ndef encodes(self, x:str): return x+'hello'\n\n@B\ndef encodes(self, x): return str(x)+'!'\n\nIf the input is not an int or str, the third encodes method will apply:\n\nb = B()\ntest_eq(b([1]), '[1]!') \ntest_eq(b([1.0]), '[1.0]!')\n\nHowever, if the input is a tuple, then the appropriate method will apply according to the type of each element in the tuple:\n\ntest_eq(b(('1',)), ('1hello',))\ntest_eq(b((1,2)), (2,3))\ntest_eq(b(('a',1.0)), ('ahello','1.0!'))\n\nDispatching over tuples works recursively, by the way:\n\nclass B(Transform):\n def encodes(self, x:int): return x+1\n def encodes(self, x:str): return x+'_hello'\n def decodes(self, x:int): return x-1\n def decodes(self, x:str): return x.replace('_hello', '')\n\nf = B()\nstart = (1.,(2,'3'))\nt = f(start)\ntest_eq_type(t, (1.,(3,'3_hello')))\ntest_eq(f.decode(t), start)\n\nDispatching also works with typing module type classes, like numbers.integral:\n\n@Transform\ndef f(x:numbers.Integral): return x+1\n\nt = f((1,'1',1))\ntest_eq(t, (2, '1', 2))\n\n\nsource\n\n\n\nInplaceTransform\n\n InplaceTransform (enc=None, dec=None, split_idx=None, order=None)\n\nA Transform that modifies in-place and just returns whatever it’s passed\n\nclass A(InplaceTransform): pass\n\n@A\ndef encodes(self, x:pd.Series): x.fillna(10, inplace=True)\n \nf = A()\n\ntest_eq_type(f(pd.Series([1,2,None])),pd.Series([1,2,10],dtype=np.float64)) #fillna fills with floats.\n\n\nsource\n\n\nDisplayedTransform\n\n DisplayedTransform (enc=None, dec=None, split_idx=None, order=None)\n\nA transform with a __repr__ that shows its attrs\nTransforms normally are represented by just their class name and a list of encodes and decodes implementations:\n\nclass A(Transform): encodes,decodes = noop,noop\nf = A()\nf\n\nA:\nencodes: (object,object) -> noop\ndecodes: (object,object) -> noop\n\n\nA DisplayedTransform will in addition show the contents of all attributes listed in the comma-delimited string self.store_attrs:\n\nclass A(DisplayedTransform):\n encodes = noop\n def __init__(self, a, b=2):\n super().__init__()\n store_attr()\n \nA(a=1,b=2)\n\nA -- {'a': 1, 'b': 2}:\nencodes: (object,object) -> noop\ndecodes: \n\n\n\nsource\n\n\nItemTransform\n\n ItemTransform (enc=None, dec=None, split_idx=None, order=None)\n\nA transform that always take tuples as items\nItemTransform is the class to use to opt out of the default behavior of Transform.\n\nclass AIT(ItemTransform): \n def encodes(self, xy): x,y=xy; return (x+y,y)\n def decodes(self, xy): x,y=xy; return (x-y,y)\n \nf = AIT()\ntest_eq(f((1,2)), (3,2))\ntest_eq(f.decode((3,2)), (1,2))\n\nIf you pass a special tuple subclass, the usual retain type behavior of Transform will keep it:\n\nclass _T(tuple): pass\nx = _T((1,2))\ntest_eq_type(f(x), _T((3,2)))\n\n\nsource\n\n\nget_func\n\n get_func (t, name, *args, **kwargs)\n\nGet the t.name (potentially partial-ized with args and kwargs) or noop if not defined\nThis works for any kind of t supporting getattr, so a class or a module.\n\ntest_eq(get_func(operator, 'neg', 2)(), -2)\ntest_eq(get_func(operator.neg, '__call__')(2), -2)\ntest_eq(get_func(list, 'foobar')([2]), [2])\na = [2,1]\nget_func(list, 'sort')(a)\ntest_eq(a, [1,2])\n\nTransforms are built with multiple-dispatch: a given function can have several methods depending on the type of the object received. This is done directly with the TypeDispatch module and type-annotation in Transform, but you can also use the following class.\n\nsource\n\n\nFunc\n\n Func (name, *args, **kwargs)\n\nBasic wrapper around a name with args and kwargs to call on a given type\nYou can call the Func object on any module name or type, even a list of types. It will return the corresponding function (with a default to noop if nothing is found) or list of functions.\n\ntest_eq(Func('sqrt')(math), math.sqrt)\n\n\n\n\nSig\n\n Sig (*args, **kwargs)\n\nSig is just sugar-syntax to create a Func object more easily with the syntax Sig.name(*args, **kwargs).\n\nf = Sig.sqrt()\ntest_eq(f(math), math.sqrt)\n\n\nsource\n\n\ncompose_tfms\n\n compose_tfms (x, tfms, is_enc=True, reverse=False, **kwargs)\n\nApply all func_nm attribute of tfms on x, maybe in reverse order\n\ndef to_int (x): return Int(x)\ndef to_float(x): return Float(x)\ndef double (x): return x*2\ndef half(x)->None: return x/2\n\n\ndef test_compose(a, b, *fs): test_eq_type(compose_tfms(a, tfms=map(Transform,fs)), b)\n\ntest_compose(1, Int(1), to_int)\ntest_compose(1, Float(1), to_int,to_float)\ntest_compose(1, Float(2), to_int,to_float,double)\ntest_compose(2.0, 2.0, to_int,double,half)\n\n\nclass A(Transform):\n def encodes(self, x:float): return Float(x+1)\n def decodes(self, x): return x-1\n \ntfms = [A(), Transform(math.sqrt)]\nt = compose_tfms(3., tfms=tfms)\ntest_eq_type(t, Float(2.))\ntest_eq(compose_tfms(t, tfms=tfms, is_enc=False), 1.)\ntest_eq(compose_tfms(4., tfms=tfms, reverse=True), 3.)\n\n\ntfms = [A(), Transform(math.sqrt)]\ntest_eq(compose_tfms((9,3.), tfms=tfms), (3,2.))\n\n\nsource\n\n\nmk_transform\n\n mk_transform (f)\n\nConvert function f to Transform if it isn’t already one\n\nsource\n\n\ngather_attrs\n\n gather_attrs (o, k, nm)\n\nUsed in getattr to collect all attrs k from self.{nm}\n\nsource\n\n\ngather_attr_names\n\n gather_attr_names (o, nm)\n\nUsed in dir to collect all attrs k from self.{nm}\n\nsource\n\n\nPipeline\n\n Pipeline (funcs=None, split_idx=None)\n\nA pipeline of composed (for encode/decode) transforms, setup with types\n\nadd_docs(Pipeline,\n __call__=\"Compose `__call__` of all `fs` on `o`\",\n decode=\"Compose `decode` of all `fs` on `o`\",\n show=\"Show `o`, a single item from a tuple, decoding as needed\",\n add=\"Add transforms `ts`\",\n setup=\"Call each tfm's `setup` in order\")\n\nPipeline is a wrapper for compose_tfms. You can pass instances of Transform or regular functions in funcs, the Pipeline will wrap them all in Transform (and instantiate them if needed) during the initialization. It handles the transform setup by adding them one at a time and calling setup on each, goes through them in order in __call__ or decode and can show an object by applying decoding the transforms up until the point it gets an object that knows how to show itself.\n\n# Empty pipeline is noop\npipe = Pipeline()\ntest_eq(pipe(1), 1)\ntest_eq(pipe((1,)), (1,))\n# Check pickle works\nassert pickle.loads(pickle.dumps(pipe))\n\n\nclass IntFloatTfm(Transform):\n def encodes(self, x): return Int(x)\n def decodes(self, x): return Float(x)\n foo=1\n\nint_tfm=IntFloatTfm()\n\ndef neg(x): return -x\nneg_tfm = Transform(neg, neg)\n\n\npipe = Pipeline([neg_tfm, int_tfm])\n\nstart = 2.0\nt = pipe(start)\ntest_eq_type(t, Int(-2))\ntest_eq_type(pipe.decode(t), Float(start))\ntest_stdout(lambda:pipe.show(t), '-2')\n\n\npipe = Pipeline([neg_tfm, int_tfm])\nt = pipe(start)\ntest_stdout(lambda:pipe.show(pipe((1.,2.))), '-1\\n-2')\ntest_eq(pipe.foo, 1)\nassert 'foo' in dir(pipe)\nassert 'int_float_tfm' in dir(pipe)\n\nYou can add a single transform or multiple transforms ts using Pipeline.add. Transforms will be ordered by Transform.order.\n\npipe = Pipeline([neg_tfm, int_tfm])\nclass SqrtTfm(Transform):\n order=-1\n def encodes(self, x): \n return x**(.5)\n def decodes(self, x): return x**2\npipe.add(SqrtTfm())\ntest_eq(pipe(4),-2)\ntest_eq(pipe.decode(-2),4)\npipe.add([SqrtTfm(),SqrtTfm()])\ntest_eq(pipe(256),-2)\ntest_eq(pipe.decode(-2),256)\n\nTransforms are available as attributes named with the snake_case version of the names of their types. Attributes in transforms can be directly accessed as attributes of the pipeline.\n\ntest_eq(pipe.int_float_tfm, int_tfm)\ntest_eq(pipe.foo, 1)\n\npipe = Pipeline([int_tfm, int_tfm])\npipe.int_float_tfm\ntest_eq(pipe.int_float_tfm[0], int_tfm)\ntest_eq(pipe.foo, [1,1])\n\n\n# Check opposite order\npipe = Pipeline([int_tfm,neg_tfm])\nt = pipe(start)\ntest_eq(t, -2)\ntest_stdout(lambda:pipe.show(t), '-2')\n\n\nclass A(Transform):\n def encodes(self, x): return int(x)\n def decodes(self, x): return Float(x)\n\npipe = Pipeline([neg_tfm, A])\nt = pipe(start)\ntest_eq_type(t, -2)\ntest_eq_type(pipe.decode(t), Float(start))\ntest_stdout(lambda:pipe.show(t), '-2.0')\n\n\ns2 = (1,2)\npipe = Pipeline([neg_tfm, A])\nt = pipe(s2)\ntest_eq_type(t, (-1,-2))\ntest_eq_type(pipe.decode(t), (Float(1.),Float(2.)))\ntest_stdout(lambda:pipe.show(t), '-1.0\\n-2.0')\n\n\nfrom PIL import Image\n\n\nclass ArrayImage(ndarray):\n _show_args = {'cmap':'viridis'}\n def __new__(cls, x, *args, **kwargs):\n if isinstance(x,tuple): super().__new__(cls, x, *args, **kwargs)\n if args or kwargs: raise RuntimeError('Unknown array init args')\n if not isinstance(x,ndarray): x = array(x)\n return x.view(cls)\n \n def show(self, ctx=None, figsize=None, **kwargs):\n if ctx is None: _,ctx = plt.subplots(figsize=figsize)\n ctx.imshow(im, **{**self._show_args, **kwargs})\n ctx.axis('off')\n return ctx\n \nim = Image.open(TEST_IMAGE)\nim_t = ArrayImage(im)\n\n\ndef f1(x:ArrayImage): return -x\ndef f2(x): return Image.open(x).resize((128,128))\ndef f3(x:Image.Image): return(ArrayImage(array(x)))\n\n\npipe = Pipeline([f2,f3,f1])\nt = pipe(TEST_IMAGE)\ntest_eq(type(t), ArrayImage)\ntest_eq(t, -array(f3(f2(TEST_IMAGE))))\n\n\npipe = Pipeline([f2,f3])\nt = pipe(TEST_IMAGE)\nax = pipe.show(t)\n\n\n\n\n\n\n\n\n\n#test_fig_exists(ax)\n\n\n#Check filtering is properly applied\nadd1 = B()\nadd1.split_idx = 1\npipe = Pipeline([neg_tfm, A(), add1])\ntest_eq(pipe(start), -2)\npipe.split_idx=1\ntest_eq(pipe(start), -1)\npipe.split_idx=0\ntest_eq(pipe(start), -2)\nfor t in [None, 0, 1]:\n pipe.split_idx=t\n test_eq(pipe.decode(pipe(start)), start)\n test_stdout(lambda: pipe.show(pipe(start)), \"-2.0\")\n\n\ndef neg(x): return -x\ntest_eq(type(mk_transform(neg)), Transform)\ntest_eq(type(mk_transform(math.sqrt)), Transform)\ntest_eq(type(mk_transform(lambda a:a*2)), Transform)\ntest_eq(type(mk_transform(Pipeline([neg]))), Pipeline)\n\n\n\nMethods\n\n#TODO: method examples\n\n\nsource\n\n\nPipeline.__call__\n\n Pipeline.__call__ (o)\n\nCall self as a function.\n\nsource\n\n\nPipeline.decode\n\n Pipeline.decode (o, full=True)\n\n\nsource\n\n\nPipeline.setup\n\n Pipeline.setup (items=None, train_setup=False)\n\nDuring the setup, the Pipeline starts with no transform and adds them one at a time, so that during its setup, each transform gets the items processed up to its point and not after.", + "crumbs": [ + "Transforms" + ] + }, + { + "objectID": "docments.html", + "href": "docments.html", + "title": "Docments", + "section": "", + "text": "docments provides programmatic access to comments in function parameters and return types. It can be used to create more developer-friendly documentation, CLI, etc tools.", + "crumbs": [ + "Docments" + ] + }, + { + "objectID": "docments.html#why", + "href": "docments.html#why", + "title": "Docments", + "section": "Why?", + "text": "Why?\nWithout docments, if you want to document your parameters, you have to repeat param names in docstrings, since they’re already in the function signature. The parameters have to be kept synchronized in the two places as you change your code. Readers of your code have to look back and forth between two places to understand what’s happening. So it’s more work for you, and for your users.\nFurthermore, to have parameter documentation formatted nicely without docments, you have to use special magic docstring formatting, often with odd quirks, which is a pain to create and maintain, and awkward to read in code. For instance, using numpy-style documentation:\n\ndef add_np(a:int, b:int=0)->int:\n \"\"\"The sum of two numbers.\n \n Used to demonstrate numpy-style docstrings.\n\nParameters\n----------\na : int\n the 1st number to add\nb : int\n the 2nd number to add (default: 0)\n\nReturns\n-------\nint\n the result of adding `a` to `b`\"\"\"\n return a+b\n\nBy comparison, here’s the same thing using docments:\n\ndef add(\n a:int, # the 1st number to add\n b=0, # the 2nd number to add\n)->int: # the result of adding `a` to `b`\n \"The sum of two numbers.\"\n return a+b", + "crumbs": [ + "Docments" + ] + }, + { + "objectID": "docments.html#numpy-docstring-helper-functions", + "href": "docments.html#numpy-docstring-helper-functions", + "title": "Docments", + "section": "Numpy docstring helper functions", + "text": "Numpy docstring helper functions\ndocments also supports numpy-style docstrings, or a mix or numpy-style and docments parameter documentation. The functions in this section help get and parse this information.\n\nsource\n\ndocstring\n\n docstring (sym)\n\nGet docstring for sym for functions ad classes\n\ntest_eq(docstring(add), \"The sum of two numbers.\")\n\n\nsource\n\n\nparse_docstring\n\n parse_docstring (sym)\n\nParse a numpy-style docstring in sym\n\n# parse_docstring(add_np)\n\n\nsource\n\n\nisdataclass\n\n isdataclass (s)\n\nCheck if s is a dataclass but not a dataclass’ instance\n\nsource\n\n\nget_dataclass_source\n\n get_dataclass_source (s)\n\nGet source code for dataclass s\n\nsource\n\n\nget_source\n\n get_source (s)\n\nGet source code for string, function object or dataclass s\n\nsource\n\n\nget_name\n\n get_name (obj)\n\nGet the name of obj\n\ntest_eq(get_name(in_ipython), 'in_ipython')\ntest_eq(get_name(L.map), 'map')\n\n\nsource\n\n\nqual_name\n\n qual_name (obj)\n\nGet the qualified name of obj\n\nassert qual_name(docscrape) == 'fastcore.docscrape'", + "crumbs": [ + "Docments" + ] + }, + { + "objectID": "docments.html#docments", + "href": "docments.html#docments", + "title": "Docments", + "section": "Docments", + "text": "Docments\n\nsource\n\ndocments\n\n docments (elt, full=False, returns=True, eval_str=False)\n\nGenerates a docment\nThe returned dict has parameter names as keys, docments as values. The return value comment appears in the return, unless returns=False. Using the add definition above, we get:\n\ndef add(\n a:int, # the 1st number to add\n b=0, # the 2nd number to add\n)->int: # the result of adding `a` to `b`\n \"The sum of two numbers.\"\n return a+b\n\ndocments(add)\n\n{ 'a': 'the 1st number to add',\n 'b': 'the 2nd number to add',\n 'return': 'the result of adding `a` to `b`'}\n\n\nIf you pass full=True, the values are dict of defaults, types, and docments as values. Note that the type annotation is inferred from the default value, if the annotation is empty and a default is supplied.\n\ndocments(add, full=True)\n\n{ 'a': { 'anno': 'int',\n 'default': <class 'inspect._empty'>,\n 'docment': 'the 1st number to add'},\n 'b': { 'anno': <class 'int'>,\n 'default': 0,\n 'docment': 'the 2nd number to add'},\n 'return': { 'anno': 'int',\n 'default': <class 'inspect._empty'>,\n 'docment': 'the result of adding `a` to `b`'}}\n\n\nTo evaluate stringified annotations (from python 3.10), use eval_str:\n\ndocments(add, full=True, eval_str=True)['a']\n\n{ 'anno': <class 'int'>,\n 'default': <class 'inspect._empty'>,\n 'docment': 'the 1st number to add'}\n\n\nIf you need more space to document a parameter, place one or more lines of comments above the parameter, or above the return type. You can mix-and-match these docment styles:\n\ndef add(\n # The first operand\n a:int,\n # This is the second of the operands to the *addition* operator.\n # Note that passing a negative value here is the equivalent of the *subtraction* operator.\n b:int,\n)->int: # The result is calculated using Python's builtin `+` operator.\n \"Add `a` to `b`\"\n return a+b\n\n\ndocments(add)\n\n{ 'a': 'The first operand',\n 'b': 'This is the second of the operands to the *addition* operator.\\n'\n 'Note that passing a negative value here is the equivalent of the '\n '*subtraction* operator.',\n 'return': \"The result is calculated using Python's builtin `+` operator.\"}\n\n\nDocments works with async functions, too:\n\nasync def add_async(\n # The first operand\n a:int,\n # This is the second of the operands to the *addition* operator.\n # Note that passing a negative value here is the equivalent of the *subtraction* operator.\n b:int,\n)->int: # The result is calculated using Python's builtin `+` operator.\n \"Add `a` to `b`\"\n return a+b\n\n\ntest_eq(docments(add_async), docments(add))\n\nYou can also use docments with classes and methods:\n\nclass Adder:\n \"An addition calculator\"\n def __init__(self,\n a:int, # First operand\n b:int, # 2nd operand\n ): self.a,self.b = a,b\n \n def calculate(self\n )->int: # Integral result of addition operator\n \"Add `a` to `b`\"\n return a+b\n\n\ndocments(Adder)\n\n{'a': 'First operand', 'b': '2nd operand', 'return': None}\n\n\n\ndocments(Adder.calculate)\n\n{'return': 'Integral result of addition operator', 'self': None}\n\n\ndocments can also be extracted from numpy-style docstrings:\n\nprint(add_np.__doc__)\n\nThe sum of two numbers.\n \n Used to demonstrate numpy-style docstrings.\n\nParameters\n----------\na : int\n the 1st number to add\nb : int\n the 2nd number to add (default: 0)\n\nReturns\n-------\nint\n the result of adding `a` to `b`\n\n\n\ndocments(add_np)\n\n{ 'a': 'the 1st number to add',\n 'b': 'the 2nd number to add (default: 0)',\n 'return': 'the result of adding `a` to `b`'}\n\n\nYou can even mix and match docments and numpy parameters:\n\ndef add_mixed(a:int, # the first number to add\n b\n )->int: # the result\n \"\"\"The sum of two numbers.\n\nParameters\n----------\nb : int\n the 2nd number to add (default: 0)\"\"\"\n return a+b\n\n\ndocments(add_mixed, full=True)\n\n{ 'a': { 'anno': 'int',\n 'default': <class 'inspect._empty'>,\n 'docment': 'the first number to add'},\n 'b': { 'anno': 'int',\n 'default': <class 'inspect._empty'>,\n 'docment': 'the 2nd number to add (default: 0)'},\n 'return': { 'anno': 'int',\n 'default': <class 'inspect._empty'>,\n 'docment': 'the result'}}\n\n\nYou can use docments with dataclasses, however if the class was defined in online notebook, docments will not contain parameters’ comments. This is because the source code is not available in the notebook. After converting the notebook to a module, the docments will be available. Thus, documentation will have correct parameters’ comments.\nDocments even works with delegates:\n\nfrom fastcore.meta import delegates\n\n\ndef _a(a:int=2): return a # First\n\n@delegates(_a)\ndef _b(b:str, **kwargs): return b, (_a(**kwargs)) # Second\n\ndocments(_b)\n\n{'a': 'First', 'b': 'Second', 'return': None}", + "crumbs": [ + "Docments" + ] + } +] \ No newline at end of file diff --git a/site_libs/bootstrap/bootstrap-icons.css b/site_libs/bootstrap/bootstrap-icons.css new file mode 100644 index 00000000..285e4448 --- /dev/null +++ b/site_libs/bootstrap/bootstrap-icons.css @@ -0,0 +1,2078 @@ +/*! + * Bootstrap Icons v1.11.1 (https://icons.getbootstrap.com/) + * Copyright 2019-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE) + */ + +@font-face { + font-display: block; + font-family: "bootstrap-icons"; + src: +url("./bootstrap-icons.woff?2820a3852bdb9a5832199cc61cec4e65") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } +.bi-1-circle-fill::before { content: "\f796"; } +.bi-1-circle::before { content: "\f797"; } +.bi-1-square-fill::before { content: "\f798"; } +.bi-1-square::before { content: "\f799"; } +.bi-2-circle-fill::before { content: "\f79c"; } +.bi-2-circle::before { content: "\f79d"; } +.bi-2-square-fill::before { content: "\f79e"; } +.bi-2-square::before { content: "\f79f"; } +.bi-3-circle-fill::before { content: "\f7a2"; } +.bi-3-circle::before { content: "\f7a3"; } +.bi-3-square-fill::before { content: "\f7a4"; } +.bi-3-square::before { content: "\f7a5"; } +.bi-4-circle-fill::before { content: "\f7a8"; } +.bi-4-circle::before { content: "\f7a9"; } +.bi-4-square-fill::before { content: "\f7aa"; } +.bi-4-square::before { content: "\f7ab"; } +.bi-5-circle-fill::before { content: "\f7ae"; } +.bi-5-circle::before { content: "\f7af"; } +.bi-5-square-fill::before { content: "\f7b0"; } +.bi-5-square::before { content: "\f7b1"; } +.bi-6-circle-fill::before { content: "\f7b4"; } +.bi-6-circle::before { content: "\f7b5"; } +.bi-6-square-fill::before { content: "\f7b6"; } +.bi-6-square::before { content: "\f7b7"; } +.bi-7-circle-fill::before { content: "\f7ba"; } +.bi-7-circle::before { content: "\f7bb"; } +.bi-7-square-fill::before { content: "\f7bc"; } +.bi-7-square::before { content: "\f7bd"; } +.bi-8-circle-fill::before { content: "\f7c0"; } +.bi-8-circle::before { content: "\f7c1"; } +.bi-8-square-fill::before { content: "\f7c2"; } +.bi-8-square::before { content: "\f7c3"; } +.bi-9-circle-fill::before { content: "\f7c6"; } +.bi-9-circle::before { content: "\f7c7"; } +.bi-9-square-fill::before { content: "\f7c8"; } +.bi-9-square::before { content: "\f7c9"; } +.bi-airplane-engines-fill::before { content: "\f7ca"; } +.bi-airplane-engines::before { content: "\f7cb"; } +.bi-airplane-fill::before { content: "\f7cc"; } +.bi-airplane::before { content: "\f7cd"; } +.bi-alexa::before { content: "\f7ce"; } +.bi-alipay::before { content: "\f7cf"; } +.bi-android::before { content: "\f7d0"; } +.bi-android2::before { content: "\f7d1"; } +.bi-box-fill::before { content: "\f7d2"; } +.bi-box-seam-fill::before { content: "\f7d3"; } +.bi-browser-chrome::before { content: "\f7d4"; } +.bi-browser-edge::before { content: "\f7d5"; } +.bi-browser-firefox::before { content: "\f7d6"; } +.bi-browser-safari::before { content: "\f7d7"; } +.bi-c-circle-fill::before { content: "\f7da"; } +.bi-c-circle::before { content: "\f7db"; } +.bi-c-square-fill::before { content: "\f7dc"; } +.bi-c-square::before { content: "\f7dd"; } +.bi-capsule-pill::before { content: "\f7de"; } +.bi-capsule::before { content: "\f7df"; } +.bi-car-front-fill::before { content: "\f7e0"; } +.bi-car-front::before { content: "\f7e1"; } +.bi-cassette-fill::before { content: "\f7e2"; } +.bi-cassette::before { content: "\f7e3"; } +.bi-cc-circle-fill::before { content: "\f7e6"; } +.bi-cc-circle::before { content: "\f7e7"; } +.bi-cc-square-fill::before { content: "\f7e8"; } +.bi-cc-square::before { content: "\f7e9"; } +.bi-cup-hot-fill::before { content: "\f7ea"; } +.bi-cup-hot::before { content: "\f7eb"; } +.bi-currency-rupee::before { content: "\f7ec"; } +.bi-dropbox::before { content: "\f7ed"; } +.bi-escape::before { content: "\f7ee"; } +.bi-fast-forward-btn-fill::before { content: "\f7ef"; } +.bi-fast-forward-btn::before { content: "\f7f0"; } +.bi-fast-forward-circle-fill::before { content: "\f7f1"; } +.bi-fast-forward-circle::before { content: "\f7f2"; } +.bi-fast-forward-fill::before { content: "\f7f3"; } +.bi-fast-forward::before { content: "\f7f4"; } +.bi-filetype-sql::before { content: "\f7f5"; } +.bi-fire::before { content: "\f7f6"; } +.bi-google-play::before { content: "\f7f7"; } +.bi-h-circle-fill::before { content: "\f7fa"; } +.bi-h-circle::before { content: "\f7fb"; } +.bi-h-square-fill::before { content: "\f7fc"; } +.bi-h-square::before { content: "\f7fd"; } +.bi-indent::before { content: "\f7fe"; } +.bi-lungs-fill::before { content: "\f7ff"; } +.bi-lungs::before { content: "\f800"; } +.bi-microsoft-teams::before { content: "\f801"; } +.bi-p-circle-fill::before { content: "\f804"; } +.bi-p-circle::before { content: "\f805"; } +.bi-p-square-fill::before { content: "\f806"; } +.bi-p-square::before { content: "\f807"; } +.bi-pass-fill::before { content: "\f808"; } +.bi-pass::before { content: "\f809"; } +.bi-prescription::before { content: "\f80a"; } +.bi-prescription2::before { content: "\f80b"; } +.bi-r-circle-fill::before { content: "\f80e"; } +.bi-r-circle::before { content: "\f80f"; } +.bi-r-square-fill::before { content: "\f810"; } +.bi-r-square::before { content: "\f811"; } +.bi-repeat-1::before { content: "\f812"; } +.bi-repeat::before { content: "\f813"; } +.bi-rewind-btn-fill::before { content: "\f814"; } +.bi-rewind-btn::before { content: "\f815"; } +.bi-rewind-circle-fill::before { content: "\f816"; } +.bi-rewind-circle::before { content: "\f817"; } +.bi-rewind-fill::before { content: "\f818"; } +.bi-rewind::before { content: "\f819"; } +.bi-train-freight-front-fill::before { content: "\f81a"; } +.bi-train-freight-front::before { content: "\f81b"; } +.bi-train-front-fill::before { content: "\f81c"; } +.bi-train-front::before { content: "\f81d"; } +.bi-train-lightrail-front-fill::before { content: "\f81e"; } +.bi-train-lightrail-front::before { content: "\f81f"; } +.bi-truck-front-fill::before { content: "\f820"; } +.bi-truck-front::before { content: "\f821"; } +.bi-ubuntu::before { content: "\f822"; } +.bi-unindent::before { content: "\f823"; } +.bi-unity::before { content: "\f824"; } +.bi-universal-access-circle::before { content: "\f825"; } +.bi-universal-access::before { content: "\f826"; } +.bi-virus::before { content: "\f827"; } +.bi-virus2::before { content: "\f828"; } +.bi-wechat::before { content: "\f829"; } +.bi-yelp::before { content: "\f82a"; } +.bi-sign-stop-fill::before { content: "\f82b"; } +.bi-sign-stop-lights-fill::before { content: "\f82c"; } +.bi-sign-stop-lights::before { content: "\f82d"; } +.bi-sign-stop::before { content: "\f82e"; } +.bi-sign-turn-left-fill::before { content: "\f82f"; } +.bi-sign-turn-left::before { content: "\f830"; } +.bi-sign-turn-right-fill::before { content: "\f831"; } +.bi-sign-turn-right::before { content: "\f832"; } +.bi-sign-turn-slight-left-fill::before { content: "\f833"; } +.bi-sign-turn-slight-left::before { content: "\f834"; } +.bi-sign-turn-slight-right-fill::before { content: "\f835"; } +.bi-sign-turn-slight-right::before { content: "\f836"; } +.bi-sign-yield-fill::before { content: "\f837"; } +.bi-sign-yield::before { content: "\f838"; } +.bi-ev-station-fill::before { content: "\f839"; } +.bi-ev-station::before { content: "\f83a"; } +.bi-fuel-pump-diesel-fill::before { content: "\f83b"; } +.bi-fuel-pump-diesel::before { content: "\f83c"; } +.bi-fuel-pump-fill::before { content: "\f83d"; } +.bi-fuel-pump::before { content: "\f83e"; } +.bi-0-circle-fill::before { content: "\f83f"; } +.bi-0-circle::before { content: "\f840"; } +.bi-0-square-fill::before { content: "\f841"; } +.bi-0-square::before { content: "\f842"; } +.bi-rocket-fill::before { content: "\f843"; } +.bi-rocket-takeoff-fill::before { content: "\f844"; } +.bi-rocket-takeoff::before { content: "\f845"; } +.bi-rocket::before { content: "\f846"; } +.bi-stripe::before { content: "\f847"; } +.bi-subscript::before { content: "\f848"; } +.bi-superscript::before { content: "\f849"; } +.bi-trello::before { content: "\f84a"; } +.bi-envelope-at-fill::before { content: "\f84b"; } +.bi-envelope-at::before { content: "\f84c"; } +.bi-regex::before { content: "\f84d"; } +.bi-text-wrap::before { content: "\f84e"; } +.bi-sign-dead-end-fill::before { content: "\f84f"; } +.bi-sign-dead-end::before { content: "\f850"; } +.bi-sign-do-not-enter-fill::before { content: "\f851"; } +.bi-sign-do-not-enter::before { content: "\f852"; } +.bi-sign-intersection-fill::before { content: "\f853"; } +.bi-sign-intersection-side-fill::before { content: "\f854"; } +.bi-sign-intersection-side::before { content: "\f855"; } +.bi-sign-intersection-t-fill::before { content: "\f856"; } +.bi-sign-intersection-t::before { content: "\f857"; } +.bi-sign-intersection-y-fill::before { content: "\f858"; } +.bi-sign-intersection-y::before { content: "\f859"; } +.bi-sign-intersection::before { content: "\f85a"; } +.bi-sign-merge-left-fill::before { content: "\f85b"; } +.bi-sign-merge-left::before { content: "\f85c"; } +.bi-sign-merge-right-fill::before { content: "\f85d"; } +.bi-sign-merge-right::before { content: "\f85e"; } +.bi-sign-no-left-turn-fill::before { content: "\f85f"; } +.bi-sign-no-left-turn::before { content: "\f860"; } +.bi-sign-no-parking-fill::before { content: "\f861"; } +.bi-sign-no-parking::before { content: "\f862"; } +.bi-sign-no-right-turn-fill::before { content: "\f863"; } +.bi-sign-no-right-turn::before { content: "\f864"; } +.bi-sign-railroad-fill::before { content: "\f865"; } +.bi-sign-railroad::before { content: "\f866"; } +.bi-building-add::before { content: "\f867"; } +.bi-building-check::before { content: "\f868"; } +.bi-building-dash::before { content: "\f869"; } +.bi-building-down::before { content: "\f86a"; } +.bi-building-exclamation::before { content: "\f86b"; } +.bi-building-fill-add::before { content: "\f86c"; } +.bi-building-fill-check::before { content: "\f86d"; } +.bi-building-fill-dash::before { content: "\f86e"; } +.bi-building-fill-down::before { content: "\f86f"; } +.bi-building-fill-exclamation::before { content: "\f870"; } +.bi-building-fill-gear::before { content: "\f871"; } +.bi-building-fill-lock::before { content: "\f872"; } +.bi-building-fill-slash::before { content: "\f873"; } +.bi-building-fill-up::before { content: "\f874"; } +.bi-building-fill-x::before { content: "\f875"; } +.bi-building-fill::before { content: "\f876"; } +.bi-building-gear::before { content: "\f877"; } +.bi-building-lock::before { content: "\f878"; } +.bi-building-slash::before { content: "\f879"; } +.bi-building-up::before { content: "\f87a"; } +.bi-building-x::before { content: "\f87b"; } +.bi-buildings-fill::before { content: "\f87c"; } +.bi-buildings::before { content: "\f87d"; } +.bi-bus-front-fill::before { content: "\f87e"; } +.bi-bus-front::before { content: "\f87f"; } +.bi-ev-front-fill::before { content: "\f880"; } +.bi-ev-front::before { content: "\f881"; } +.bi-globe-americas::before { content: "\f882"; } +.bi-globe-asia-australia::before { content: "\f883"; } +.bi-globe-central-south-asia::before { content: "\f884"; } +.bi-globe-europe-africa::before { content: "\f885"; } +.bi-house-add-fill::before { content: "\f886"; } +.bi-house-add::before { content: "\f887"; } +.bi-house-check-fill::before { content: "\f888"; } +.bi-house-check::before { content: "\f889"; } +.bi-house-dash-fill::before { content: "\f88a"; } +.bi-house-dash::before { content: "\f88b"; } +.bi-house-down-fill::before { content: "\f88c"; } +.bi-house-down::before { content: "\f88d"; } +.bi-house-exclamation-fill::before { content: "\f88e"; } +.bi-house-exclamation::before { content: "\f88f"; } +.bi-house-gear-fill::before { content: "\f890"; } +.bi-house-gear::before { content: "\f891"; } +.bi-house-lock-fill::before { content: "\f892"; } +.bi-house-lock::before { content: "\f893"; } +.bi-house-slash-fill::before { content: "\f894"; } +.bi-house-slash::before { content: "\f895"; } +.bi-house-up-fill::before { content: "\f896"; } +.bi-house-up::before { content: "\f897"; } +.bi-house-x-fill::before { content: "\f898"; } +.bi-house-x::before { content: "\f899"; } +.bi-person-add::before { content: "\f89a"; } +.bi-person-down::before { content: "\f89b"; } +.bi-person-exclamation::before { content: "\f89c"; } +.bi-person-fill-add::before { content: "\f89d"; } +.bi-person-fill-check::before { content: "\f89e"; } +.bi-person-fill-dash::before { content: "\f89f"; } +.bi-person-fill-down::before { content: "\f8a0"; } +.bi-person-fill-exclamation::before { content: "\f8a1"; } +.bi-person-fill-gear::before { content: "\f8a2"; } +.bi-person-fill-lock::before { content: "\f8a3"; } +.bi-person-fill-slash::before { content: "\f8a4"; } +.bi-person-fill-up::before { content: "\f8a5"; } +.bi-person-fill-x::before { content: "\f8a6"; } +.bi-person-gear::before { content: "\f8a7"; } +.bi-person-lock::before { content: "\f8a8"; } +.bi-person-slash::before { content: "\f8a9"; } +.bi-person-up::before { content: "\f8aa"; } +.bi-scooter::before { content: "\f8ab"; } +.bi-taxi-front-fill::before { content: "\f8ac"; } +.bi-taxi-front::before { content: "\f8ad"; } +.bi-amd::before { content: "\f8ae"; } +.bi-database-add::before { content: "\f8af"; } +.bi-database-check::before { content: "\f8b0"; } +.bi-database-dash::before { content: "\f8b1"; } +.bi-database-down::before { content: "\f8b2"; } +.bi-database-exclamation::before { content: "\f8b3"; } +.bi-database-fill-add::before { content: "\f8b4"; } +.bi-database-fill-check::before { content: "\f8b5"; } +.bi-database-fill-dash::before { content: "\f8b6"; } +.bi-database-fill-down::before { content: "\f8b7"; } +.bi-database-fill-exclamation::before { content: "\f8b8"; } +.bi-database-fill-gear::before { content: "\f8b9"; } +.bi-database-fill-lock::before { content: "\f8ba"; } +.bi-database-fill-slash::before { content: "\f8bb"; } +.bi-database-fill-up::before { content: "\f8bc"; } +.bi-database-fill-x::before { content: "\f8bd"; } +.bi-database-fill::before { content: "\f8be"; } +.bi-database-gear::before { content: "\f8bf"; } +.bi-database-lock::before { content: "\f8c0"; } +.bi-database-slash::before { content: "\f8c1"; } +.bi-database-up::before { content: "\f8c2"; } +.bi-database-x::before { content: "\f8c3"; } +.bi-database::before { content: "\f8c4"; } +.bi-houses-fill::before { content: "\f8c5"; } +.bi-houses::before { content: "\f8c6"; } +.bi-nvidia::before { content: "\f8c7"; } +.bi-person-vcard-fill::before { content: "\f8c8"; } +.bi-person-vcard::before { content: "\f8c9"; } +.bi-sina-weibo::before { content: "\f8ca"; } +.bi-tencent-qq::before { content: "\f8cb"; } +.bi-wikipedia::before { content: "\f8cc"; } +.bi-alphabet-uppercase::before { content: "\f2a5"; } +.bi-alphabet::before { content: "\f68a"; } +.bi-amazon::before { content: "\f68d"; } +.bi-arrows-collapse-vertical::before { content: "\f690"; } +.bi-arrows-expand-vertical::before { content: "\f695"; } +.bi-arrows-vertical::before { content: "\f698"; } +.bi-arrows::before { content: "\f6a2"; } +.bi-ban-fill::before { content: "\f6a3"; } +.bi-ban::before { content: "\f6b6"; } +.bi-bing::before { content: "\f6c2"; } +.bi-cake::before { content: "\f6e0"; } +.bi-cake2::before { content: "\f6ed"; } +.bi-cookie::before { content: "\f6ee"; } +.bi-copy::before { content: "\f759"; } +.bi-crosshair::before { content: "\f769"; } +.bi-crosshair2::before { content: "\f794"; } +.bi-emoji-astonished-fill::before { content: "\f795"; } +.bi-emoji-astonished::before { content: "\f79a"; } +.bi-emoji-grimace-fill::before { content: "\f79b"; } +.bi-emoji-grimace::before { content: "\f7a0"; } +.bi-emoji-grin-fill::before { content: "\f7a1"; } +.bi-emoji-grin::before { content: "\f7a6"; } +.bi-emoji-surprise-fill::before { content: "\f7a7"; } +.bi-emoji-surprise::before { content: "\f7ac"; } +.bi-emoji-tear-fill::before { content: "\f7ad"; } +.bi-emoji-tear::before { content: "\f7b2"; } +.bi-envelope-arrow-down-fill::before { content: "\f7b3"; } +.bi-envelope-arrow-down::before { content: "\f7b8"; } +.bi-envelope-arrow-up-fill::before { content: "\f7b9"; } +.bi-envelope-arrow-up::before { content: "\f7be"; } +.bi-feather::before { content: "\f7bf"; } +.bi-feather2::before { content: "\f7c4"; } +.bi-floppy-fill::before { content: "\f7c5"; } +.bi-floppy::before { content: "\f7d8"; } +.bi-floppy2-fill::before { content: "\f7d9"; } +.bi-floppy2::before { content: "\f7e4"; } +.bi-gitlab::before { content: "\f7e5"; } +.bi-highlighter::before { content: "\f7f8"; } +.bi-marker-tip::before { content: "\f802"; } +.bi-nvme-fill::before { content: "\f803"; } +.bi-nvme::before { content: "\f80c"; } +.bi-opencollective::before { content: "\f80d"; } +.bi-pci-card-network::before { content: "\f8cd"; } +.bi-pci-card-sound::before { content: "\f8ce"; } +.bi-radar::before { content: "\f8cf"; } +.bi-send-arrow-down-fill::before { content: "\f8d0"; } +.bi-send-arrow-down::before { content: "\f8d1"; } +.bi-send-arrow-up-fill::before { content: "\f8d2"; } +.bi-send-arrow-up::before { content: "\f8d3"; } +.bi-sim-slash-fill::before { content: "\f8d4"; } +.bi-sim-slash::before { content: "\f8d5"; } +.bi-sourceforge::before { content: "\f8d6"; } +.bi-substack::before { content: "\f8d7"; } +.bi-threads-fill::before { content: "\f8d8"; } +.bi-threads::before { content: "\f8d9"; } +.bi-transparency::before { content: "\f8da"; } +.bi-twitter-x::before { content: "\f8db"; } +.bi-type-h4::before { content: "\f8dc"; } +.bi-type-h5::before { content: "\f8dd"; } +.bi-type-h6::before { content: "\f8de"; } +.bi-backpack-fill::before { content: "\f8df"; } +.bi-backpack::before { content: "\f8e0"; } +.bi-backpack2-fill::before { content: "\f8e1"; } +.bi-backpack2::before { content: "\f8e2"; } +.bi-backpack3-fill::before { content: "\f8e3"; } +.bi-backpack3::before { content: "\f8e4"; } +.bi-backpack4-fill::before { content: "\f8e5"; } +.bi-backpack4::before { content: "\f8e6"; } +.bi-brilliance::before { content: "\f8e7"; } +.bi-cake-fill::before { content: "\f8e8"; } +.bi-cake2-fill::before { content: "\f8e9"; } +.bi-duffle-fill::before { content: "\f8ea"; } +.bi-duffle::before { content: "\f8eb"; } +.bi-exposure::before { content: "\f8ec"; } +.bi-gender-neuter::before { content: "\f8ed"; } +.bi-highlights::before { content: "\f8ee"; } +.bi-luggage-fill::before { content: "\f8ef"; } +.bi-luggage::before { content: "\f8f0"; } +.bi-mailbox-flag::before { content: "\f8f1"; } +.bi-mailbox2-flag::before { content: "\f8f2"; } +.bi-noise-reduction::before { content: "\f8f3"; } +.bi-passport-fill::before { content: "\f8f4"; } +.bi-passport::before { content: "\f8f5"; } +.bi-person-arms-up::before { content: "\f8f6"; } +.bi-person-raised-hand::before { content: "\f8f7"; } +.bi-person-standing-dress::before { content: "\f8f8"; } +.bi-person-standing::before { content: "\f8f9"; } +.bi-person-walking::before { content: "\f8fa"; } +.bi-person-wheelchair::before { content: "\f8fb"; } +.bi-shadows::before { content: "\f8fc"; } +.bi-suitcase-fill::before { content: "\f8fd"; } +.bi-suitcase-lg-fill::before { content: "\f8fe"; } +.bi-suitcase-lg::before { content: "\f8ff"; } +.bi-suitcase::before { content: "\f900"; } +.bi-suitcase2-fill::before { content: "\f901"; } +.bi-suitcase2::before { content: "\f902"; } +.bi-vignette::before { content: "\f903"; } diff --git a/site_libs/bootstrap/bootstrap-icons.woff b/site_libs/bootstrap/bootstrap-icons.woff new file mode 100644 index 0000000000000000000000000000000000000000..dbeeb055674125ad78fda0f3d166b36e5cc92336 GIT binary patch literal 176200 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

2+UrCZlNAp`)&G@jg{m-!Dn; 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πR(XEyYV3az{Ot$Y*f93mYq^Lnu{qbYp!X!TA9&! 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 F?~0aZ)an2L literal 0 HcmV?d00001 diff --git a/site_libs/bootstrap/bootstrap.min.css b/site_libs/bootstrap/bootstrap.min.css new file mode 100644 index 00000000..2ff60158 --- /dev/null +++ b/site_libs/bootstrap/bootstrap.min.css @@ -0,0 +1,12 @@ +/*! + * Bootstrap v5.3.1 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */@import"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;700&display=swap";:root,[data-bs-theme=light]{--bs-blue: #2780e3;--bs-indigo: #6610f2;--bs-purple: #613d7c;--bs-pink: #e83e8c;--bs-red: #ff0039;--bs-orange: #f0ad4e;--bs-yellow: #ff7518;--bs-green: #3fb618;--bs-teal: #20c997;--bs-cyan: #9954bb;--bs-black: #000;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #343a40;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #343a40;--bs-gray-900: #212529;--bs-default: #343a40;--bs-primary: #2780e3;--bs-secondary: #343a40;--bs-success: #3fb618;--bs-info: #9954bb;--bs-warning: #ff7518;--bs-danger: #ff0039;--bs-light: #f8f9fa;--bs-dark: #343a40;--bs-default-rgb: 52, 58, 64;--bs-primary-rgb: 39, 128, 227;--bs-secondary-rgb: 52, 58, 64;--bs-success-rgb: 63, 182, 24;--bs-info-rgb: 153, 84, 187;--bs-warning-rgb: 255, 117, 24;--bs-danger-rgb: 255, 0, 57;--bs-light-rgb: 248, 249, 250;--bs-dark-rgb: 52, 58, 64;--bs-primary-text-emphasis: #10335b;--bs-secondary-text-emphasis: #15171a;--bs-success-text-emphasis: #19490a;--bs-info-text-emphasis: #3d224b;--bs-warning-text-emphasis: #662f0a;--bs-danger-text-emphasis: #660017;--bs-light-text-emphasis: #495057;--bs-dark-text-emphasis: #495057;--bs-primary-bg-subtle: #d4e6f9;--bs-secondary-bg-subtle: #d6d8d9;--bs-success-bg-subtle: #d9f0d1;--bs-info-bg-subtle: #ebddf1;--bs-warning-bg-subtle: #ffe3d1;--bs-danger-bg-subtle: #ffccd7;--bs-light-bg-subtle: #fcfcfd;--bs-dark-bg-subtle: #ced4da;--bs-primary-border-subtle: #a9ccf4;--bs-secondary-border-subtle: #aeb0b3;--bs-success-border-subtle: #b2e2a3;--bs-info-border-subtle: #d6bbe4;--bs-warning-border-subtle: #ffc8a3;--bs-danger-border-subtle: #ff99b0;--bs-light-border-subtle: #e9ecef;--bs-dark-border-subtle: #adb5bd;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-font-sans-serif: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 17px;--bs-body-font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-body-font-size:1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #343a40;--bs-body-color-rgb: 52, 58, 64;--bs-body-bg: #fff;--bs-body-bg-rgb: 255, 255, 255;--bs-emphasis-color: #000;--bs-emphasis-color-rgb: 0, 0, 0;--bs-secondary-color: rgba(52, 58, 64, 0.75);--bs-secondary-color-rgb: 52, 58, 64;--bs-secondary-bg: #e9ecef;--bs-secondary-bg-rgb: 233, 236, 239;--bs-tertiary-color: rgba(52, 58, 64, 0.5);--bs-tertiary-color-rgb: 52, 58, 64;--bs-tertiary-bg: #f8f9fa;--bs-tertiary-bg-rgb: 248, 249, 250;--bs-heading-color: inherit;--bs-link-color: #2761e3;--bs-link-color-rgb: 39, 97, 227;--bs-link-decoration: underline;--bs-link-hover-color: #1f4eb6;--bs-link-hover-color-rgb: 31, 78, 182;--bs-code-color: #7d12ba;--bs-highlight-bg: #ffe3d1;--bs-border-width: 1px;--bs-border-style: solid;--bs-border-color: #dee2e6;--bs-border-color-translucent: rgba(0, 0, 0, 0.175);--bs-border-radius: 0.25rem;--bs-border-radius-sm: 0.2em;--bs-border-radius-lg: 0.5rem;--bs-border-radius-xl: 1rem;--bs-border-radius-xxl: 2rem;--bs-border-radius-2xl: var(--bs-border-radius-xxl);--bs-border-radius-pill: 50rem;--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width: 0.25rem;--bs-focus-ring-opacity: 0.25;--bs-focus-ring-color: rgba(39, 128, 227, 0.25);--bs-form-valid-color: #3fb618;--bs-form-valid-border-color: #3fb618;--bs-form-invalid-color: #ff0039;--bs-form-invalid-border-color: #ff0039}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color: #dee2e6;--bs-body-color-rgb: 222, 226, 230;--bs-body-bg: #212529;--bs-body-bg-rgb: 33, 37, 41;--bs-emphasis-color: #fff;--bs-emphasis-color-rgb: 255, 255, 255;--bs-secondary-color: rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb: 222, 226, 230;--bs-secondary-bg: #343a40;--bs-secondary-bg-rgb: 52, 58, 64;--bs-tertiary-color: rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb: 222, 226, 230;--bs-tertiary-bg: #2b3035;--bs-tertiary-bg-rgb: 43, 48, 53;--bs-primary-text-emphasis: #7db3ee;--bs-secondary-text-emphasis: #85898c;--bs-success-text-emphasis: #8cd374;--bs-info-text-emphasis: #c298d6;--bs-warning-text-emphasis: #ffac74;--bs-danger-text-emphasis: #ff6688;--bs-light-text-emphasis: #f8f9fa;--bs-dark-text-emphasis: #dee2e6;--bs-primary-bg-subtle: #081a2d;--bs-secondary-bg-subtle: #0a0c0d;--bs-success-bg-subtle: #0d2405;--bs-info-bg-subtle: #1f1125;--bs-warning-bg-subtle: #331705;--bs-danger-bg-subtle: #33000b;--bs-light-bg-subtle: #343a40;--bs-dark-bg-subtle: #1a1d20;--bs-primary-border-subtle: #174d88;--bs-secondary-border-subtle: #1f2326;--bs-success-border-subtle: #266d0e;--bs-info-border-subtle: #5c3270;--bs-warning-border-subtle: #99460e;--bs-danger-border-subtle: #990022;--bs-light-border-subtle: #495057;--bs-dark-border-subtle: #343a40;--bs-heading-color: inherit;--bs-link-color: #7db3ee;--bs-link-hover-color: #97c2f1;--bs-link-color-rgb: 125, 179, 238;--bs-link-hover-color-rgb: 151, 194, 241;--bs-code-color: white;--bs-border-color: #495057;--bs-border-color-translucent: rgba(255, 255, 255, 0.15);--bs-form-valid-color: #8cd374;--bs-form-valid-border-color: #8cd374;--bs-form-invalid-color: #ff6688;--bs-form-invalid-border-color: #ff6688}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2;color:var(--bs-heading-color)}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.29rem + 0.48vw)}@media(min-width: 1200px){h2,.h2{font-size:1.65rem}}h3,.h3{font-size:calc(1.27rem + 0.24vw)}@media(min-width: 1200px){h3,.h3{font-size:1.45rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #e9ecef}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small{font-size:0.875em}mark,.mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{--bs-link-color-rgb: var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f8f9fa;padding:.5rem;border:1px solid var(--bs-border-color, #dee2e6)}pre code{background-color:rgba(0,0,0,0);font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:var(--bs-code-color);background-color:#f8f9fa;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#343a40}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:rgba(52,58,64,.75);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none !important}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:rgba(52,58,64,.75)}.container,.container-fluid,.container-xxl,.container-xl,.container-lg,.container-md,.container-sm{--bs-gutter-x: 1.5rem;--bs-gutter-y: 0;width:100%;padding-right:calc(var(--bs-gutter-x)*.5);padding-left:calc(var(--bs-gutter-x)*.5);margin-right:auto;margin-left:auto}@media(min-width: 576px){.container-sm,.container{max-width:540px}}@media(min-width: 768px){.container-md,.container-sm,.container{max-width:720px}}@media(min-width: 992px){.container-lg,.container-md,.container-sm,.container{max-width:960px}}@media(min-width: 1200px){.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1140px}}@media(min-width: 1400px){.container-xxl,.container-xl,.container-lg,.container-md,.container-sm,.container{max-width:1320px}}:root{--bs-breakpoint-xs: 0;--bs-breakpoint-sm: 576px;--bs-breakpoint-md: 768px;--bs-breakpoint-lg: 992px;--bs-breakpoint-xl: 1200px;--bs-breakpoint-xxl: 1400px}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table{--bs-table-color-type: initial;--bs-table-bg-type: initial;--bs-table-color-state: initial;--bs-table-bg-state: initial;--bs-table-color: #343a40;--bs-table-bg: #fff;--bs-table-border-color: #dee2e6;--bs-table-accent-bg: transparent;--bs-table-striped-color: #343a40;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #343a40;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #343a40;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(1px*2) solid #b2bac1}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(even){--bs-table-color-type: var(--bs-table-striped-color);--bs-table-bg-type: var(--bs-table-striped-bg)}.table-active{--bs-table-color-state: var(--bs-table-active-color);--bs-table-bg-state: var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state: var(--bs-table-hover-color);--bs-table-bg-state: var(--bs-table-hover-bg)}.table-primary{--bs-table-color: #000;--bs-table-bg: #d4e6f9;--bs-table-border-color: #bfcfe0;--bs-table-striped-bg: #c9dbed;--bs-table-striped-color: #000;--bs-table-active-bg: #bfcfe0;--bs-table-active-color: #000;--bs-table-hover-bg: #c4d5e6;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color: #000;--bs-table-bg: #d6d8d9;--bs-table-border-color: #c1c2c3;--bs-table-striped-bg: #cbcdce;--bs-table-striped-color: #000;--bs-table-active-bg: #c1c2c3;--bs-table-active-color: #000;--bs-table-hover-bg: #c6c8c9;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color: #000;--bs-table-bg: #d9f0d1;--bs-table-border-color: #c3d8bc;--bs-table-striped-bg: #cee4c7;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d8bc;--bs-table-active-color: #000;--bs-table-hover-bg: #c9dec1;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color: #000;--bs-table-bg: #ebddf1;--bs-table-border-color: #d4c7d9;--bs-table-striped-bg: #dfd2e5;--bs-table-striped-color: #000;--bs-table-active-bg: #d4c7d9;--bs-table-active-color: #000;--bs-table-hover-bg: #d9ccdf;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color: #000;--bs-table-bg: #ffe3d1;--bs-table-border-color: #e6ccbc;--bs-table-striped-bg: #f2d8c7;--bs-table-striped-color: #000;--bs-table-active-bg: #e6ccbc;--bs-table-active-color: #000;--bs-table-hover-bg: #ecd2c1;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color: #000;--bs-table-bg: #ffccd7;--bs-table-border-color: #e6b8c2;--bs-table-striped-bg: #f2c2cc;--bs-table-striped-color: #000;--bs-table-active-bg: #e6b8c2;--bs-table-active-color: #000;--bs-table-hover-bg: #ecbdc7;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color: #000;--bs-table-bg: #f8f9fa;--bs-table-border-color: #dfe0e1;--bs-table-striped-bg: #ecedee;--bs-table-striped-color: #000;--bs-table-active-bg: #dfe0e1;--bs-table-active-color: #000;--bs-table-hover-bg: #e5e6e7;--bs-table-hover-color: #000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color: #fff;--bs-table-bg: #343a40;--bs-table-border-color: #484e53;--bs-table-striped-bg: #3e444a;--bs-table-striped-color: #fff;--bs-table-active-bg: #484e53;--bs-table-active-color: #fff;--bs-table-hover-bg: #43494e;--bs-table-hover-color: #fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:rgba(52,58,64,.75)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#343a40;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-clip:padding-box;border:1px solid #dee2e6;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#343a40;background-color:#fff;border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:rgba(52,58,64,.75);opacity:1}.form-control:disabled{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#343a40;background-color:#f8f9fa;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#e9ecef}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#343a40;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2));padding:.25rem .5rem;font-size:0.875rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2));padding:.5rem 1rem;font-size:1.25rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + calc(1px * 2))}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + calc(1px * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(1px * 2))}.form-control-color{width:3rem;height:calc(1.5em + 0.75rem + calc(1px * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0 !important}.form-control-color::-webkit-color-swatch{border:0 !important}.form-control-color.form-control-sm{height:calc(1.5em + 0.5rem + calc(1px * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(1px * 2))}.form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#343a40;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#fff;background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #dee2e6;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #343a40}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-reverse{padding-right:0;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:0;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{--bs-form-check-bg: #fff;width:1em;height:1em;margin-top:.25em;vertical-align:top;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid #dee2e6;print-color-adjust:exact}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#2780e3;border-color:#2780e3}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#2780e3;border-color:#2780e3;--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{cursor:default;opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2393c0f1'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:rgba(0,0,0,0)}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#bed9f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0)}.form-range::-moz-range-thumb{width:1rem;height:1rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#bed9f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#f8f9fa;border-color:rgba(0,0,0,0)}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:rgba(52,58,64,.75)}.form-range:disabled::-moz-range-thumb{background-color:rgba(52,58,64,.75)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(1px * 2));min-height:calc(3.5rem + calc(1px * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid rgba(0,0,0,0);transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control::placeholder,.form-floating>.form-control-plaintext::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown),.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill,.form-floating>.form-control-plaintext:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-control-plaintext~label,.form-floating>.form-select~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:focus~label::after,.form-floating>.form-control:not(:placeholder-shown)~label::after,.form-floating>.form-control-plaintext~label::after,.form-floating>.form-select~label::after{position:absolute;inset:1rem .375rem;z-index:-1;height:1.5em;content:"";background-color:#fff}.form-floating>.form-control:-webkit-autofill~label{color:rgba(var(--bs-body-color-rgb), 0.65);transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.form-floating>:disabled~label,.form-floating>.form-control:disabled~label{color:#6c757d}.form-floating>:disabled~label::after,.form-floating>.form-control:disabled~label::after{background-color:#e9ecef}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select,.input-group>.form-floating{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus,.input-group>.form-floating:focus-within{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#343a40;text-align:center;white-space:nowrap;background-color:#f8f9fa;border:1px solid #dee2e6}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(1px*-1)}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#3fb618}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#3fb618}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#3fb618;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#3fb618}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-control-color:valid,.form-control-color.is-valid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#3fb618}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#3fb618}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#3fb618}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):valid,.input-group>.form-control:not(:focus).is-valid,.was-validated .input-group>.form-select:not(:focus):valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.input-group>.form-floating:not(:focus-within).is-valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#ff0039}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:#ff0039}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff0039;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff0039}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-control-color:invalid,.form-control-color.is-invalid{width:calc(3rem + calc(1.5em + 0.75rem))}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff0039}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff0039}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#ff0039}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group>.form-control:not(:focus):invalid,.input-group>.form-control:not(:focus).is-invalid,.was-validated .input-group>.form-select:not(:focus):invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.input-group>.form-floating:not(:focus-within).is-invalid{z-index:4}.btn{--bs-btn-padding-x: 0.75rem;--bs-btn-padding-y: 0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: #343a40;--bs-btn-bg: transparent;--bs-btn-border-width: 1px;--bs-btn-border-color: transparent;--bs-btn-border-radius: 0.25rem;--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity: 0.65;--bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,:not(.btn-check)+.btn:active,.btn:first-child:active,.btn.active,.btn.show{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,:not(.btn-check)+.btn:active:focus-visible,.btn:first-child:active:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-default{--bs-btn-color: #fff;--bs-btn-bg: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #2c3136;--bs-btn-hover-border-color: #2a2e33;--bs-btn-focus-shadow-rgb: 82, 88, 93;--bs-btn-active-color: #fff;--bs-btn-active-bg: #2a2e33;--bs-btn-active-border-color: #272c30;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #343a40;--bs-btn-disabled-border-color: #343a40}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #2780e3;--bs-btn-border-color: #2780e3;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #216dc1;--bs-btn-hover-border-color: #1f66b6;--bs-btn-focus-shadow-rgb: 71, 147, 231;--bs-btn-active-color: #fff;--bs-btn-active-bg: #1f66b6;--bs-btn-active-border-color: #1d60aa;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #2780e3;--bs-btn-disabled-border-color: #2780e3}.btn-secondary{--bs-btn-color: #fff;--bs-btn-bg: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #2c3136;--bs-btn-hover-border-color: #2a2e33;--bs-btn-focus-shadow-rgb: 82, 88, 93;--bs-btn-active-color: #fff;--bs-btn-active-bg: #2a2e33;--bs-btn-active-border-color: #272c30;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #343a40;--bs-btn-disabled-border-color: #343a40}.btn-success{--bs-btn-color: #fff;--bs-btn-bg: #3fb618;--bs-btn-border-color: #3fb618;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #369b14;--bs-btn-hover-border-color: #329213;--bs-btn-focus-shadow-rgb: 92, 193, 59;--bs-btn-active-color: #fff;--bs-btn-active-bg: #329213;--bs-btn-active-border-color: #2f8912;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #3fb618;--bs-btn-disabled-border-color: #3fb618}.btn-info{--bs-btn-color: #fff;--bs-btn-bg: #9954bb;--bs-btn-border-color: #9954bb;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #82479f;--bs-btn-hover-border-color: #7a4396;--bs-btn-focus-shadow-rgb: 168, 110, 197;--bs-btn-active-color: #fff;--bs-btn-active-bg: #7a4396;--bs-btn-active-border-color: #733f8c;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #9954bb;--bs-btn-disabled-border-color: #9954bb}.btn-warning{--bs-btn-color: #fff;--bs-btn-bg: #ff7518;--bs-btn-border-color: #ff7518;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #d96314;--bs-btn-hover-border-color: #cc5e13;--bs-btn-focus-shadow-rgb: 255, 138, 59;--bs-btn-active-color: #fff;--bs-btn-active-bg: #cc5e13;--bs-btn-active-border-color: #bf5812;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #ff7518;--bs-btn-disabled-border-color: #ff7518}.btn-danger{--bs-btn-color: #fff;--bs-btn-bg: #ff0039;--bs-btn-border-color: #ff0039;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #d90030;--bs-btn-hover-border-color: #cc002e;--bs-btn-focus-shadow-rgb: 255, 38, 87;--bs-btn-active-color: #fff;--bs-btn-active-bg: #cc002e;--bs-btn-active-border-color: #bf002b;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #ff0039;--bs-btn-disabled-border-color: #ff0039}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.btn-dark{--bs-btn-color: #fff;--bs-btn-bg: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #52585d;--bs-btn-hover-border-color: #484e53;--bs-btn-focus-shadow-rgb: 82, 88, 93;--bs-btn-active-color: #fff;--bs-btn-active-bg: #5d6166;--bs-btn-active-border-color: #484e53;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #343a40;--bs-btn-disabled-border-color: #343a40}.btn-outline-default{--bs-btn-color: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #343a40;--bs-btn-hover-border-color: #343a40;--bs-btn-focus-shadow-rgb: 52, 58, 64;--bs-btn-active-color: #fff;--bs-btn-active-bg: #343a40;--bs-btn-active-border-color: #343a40;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #343a40;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #343a40;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-primary{--bs-btn-color: #2780e3;--bs-btn-border-color: #2780e3;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #2780e3;--bs-btn-hover-border-color: #2780e3;--bs-btn-focus-shadow-rgb: 39, 128, 227;--bs-btn-active-color: #fff;--bs-btn-active-bg: #2780e3;--bs-btn-active-border-color: #2780e3;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #2780e3;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #2780e3;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-secondary{--bs-btn-color: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #343a40;--bs-btn-hover-border-color: #343a40;--bs-btn-focus-shadow-rgb: 52, 58, 64;--bs-btn-active-color: #fff;--bs-btn-active-bg: #343a40;--bs-btn-active-border-color: #343a40;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #343a40;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #343a40;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-success{--bs-btn-color: #3fb618;--bs-btn-border-color: #3fb618;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #3fb618;--bs-btn-hover-border-color: #3fb618;--bs-btn-focus-shadow-rgb: 63, 182, 24;--bs-btn-active-color: #fff;--bs-btn-active-bg: #3fb618;--bs-btn-active-border-color: #3fb618;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #3fb618;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #3fb618;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-info{--bs-btn-color: #9954bb;--bs-btn-border-color: #9954bb;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #9954bb;--bs-btn-hover-border-color: #9954bb;--bs-btn-focus-shadow-rgb: 153, 84, 187;--bs-btn-active-color: #fff;--bs-btn-active-bg: #9954bb;--bs-btn-active-border-color: #9954bb;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #9954bb;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #9954bb;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-warning{--bs-btn-color: #ff7518;--bs-btn-border-color: #ff7518;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #ff7518;--bs-btn-hover-border-color: #ff7518;--bs-btn-focus-shadow-rgb: 255, 117, 24;--bs-btn-active-color: #fff;--bs-btn-active-bg: #ff7518;--bs-btn-active-border-color: #ff7518;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ff7518;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #ff7518;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-danger{--bs-btn-color: #ff0039;--bs-btn-border-color: #ff0039;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #ff0039;--bs-btn-hover-border-color: #ff0039;--bs-btn-focus-shadow-rgb: 255, 0, 57;--bs-btn-active-color: #fff;--bs-btn-active-bg: #ff0039;--bs-btn-active-border-color: #ff0039;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #ff0039;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #ff0039;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-light{--bs-btn-color: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #f8f9fa;--bs-btn-hover-border-color: #f8f9fa;--bs-btn-focus-shadow-rgb: 248, 249, 250;--bs-btn-active-color: #000;--bs-btn-active-bg: #f8f9fa;--bs-btn-active-border-color: #f8f9fa;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #f8f9fa;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #f8f9fa;--bs-btn-bg: transparent;--bs-gradient: none}.btn-outline-dark{--bs-btn-color: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #343a40;--bs-btn-hover-border-color: #343a40;--bs-btn-focus-shadow-rgb: 52, 58, 64;--bs-btn-active-color: #fff;--bs-btn-active-bg: #343a40;--bs-btn-active-border-color: #343a40;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #343a40;--bs-btn-disabled-bg: transparent;--bs-btn-disabled-border-color: #343a40;--bs-btn-bg: transparent;--bs-gradient: none}.btn-link{--bs-btn-font-weight: 400;--bs-btn-color: #2761e3;--bs-btn-bg: transparent;--bs-btn-border-color: transparent;--bs-btn-hover-color: #1f4eb6;--bs-btn-hover-border-color: transparent;--bs-btn-active-color: #1f4eb6;--bs-btn-active-border-color: transparent;--bs-btn-disabled-color: #6c757d;--bs-btn-disabled-border-color: transparent;--bs-btn-box-shadow: 0 0 0 #000;--bs-btn-focus-shadow-rgb: 71, 121, 231;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-lg,.btn-group-lg>.btn{--bs-btn-padding-y: 0.5rem;--bs-btn-padding-x: 1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius: 0.5rem}.btn-sm,.btn-group-sm>.btn{--bs-btn-padding-y: 0.25rem;--bs-btn-padding-x: 0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius: 0.2em}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart,.dropup-center,.dropdown-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex: 1000;--bs-dropdown-min-width: 10rem;--bs-dropdown-padding-x: 0;--bs-dropdown-padding-y: 0.5rem;--bs-dropdown-spacer: 0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color: #343a40;--bs-dropdown-bg: #fff;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-border-radius: 0.25rem;--bs-dropdown-border-width: 1px;--bs-dropdown-inner-border-radius: calc(0.25rem - 1px);--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-divider-margin-y: 0.5rem;--bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-dropdown-link-color: #343a40;--bs-dropdown-link-hover-color: #343a40;--bs-dropdown-link-hover-bg: #f8f9fa;--bs-dropdown-link-active-color: #fff;--bs-dropdown-link-active-bg: #2780e3;--bs-dropdown-link-disabled-color: rgba(52, 58, 64, 0.5);--bs-dropdown-item-padding-x: 1rem;--bs-dropdown-item-padding-y: 0.25rem;--bs-dropdown-header-color: #6c757d;--bs-dropdown-header-padding-x: 1rem;--bs-dropdown-header-padding-y: 0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:rgba(0,0,0,0);border:0}.dropdown-item:hover,.dropdown-item:focus{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:0.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color: #dee2e6;--bs-dropdown-bg: #343a40;--bs-dropdown-border-color: rgba(0, 0, 0, 0.175);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color: #dee2e6;--bs-dropdown-link-hover-color: #fff;--bs-dropdown-divider-bg: rgba(0, 0, 0, 0.175);--bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color: #fff;--bs-dropdown-link-active-bg: #2780e3;--bs-dropdown-link-disabled-color: #adb5bd;--bs-dropdown-header-color: #adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>:not(.btn-check:first-child)+.btn,.btn-group>.btn-group:not(:first-child){margin-left:calc(1px*-1)}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:calc(1px*-1)}.nav{--bs-nav-link-padding-x: 1rem;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: #2761e3;--bs-nav-link-hover-color: #1f4eb6;--bs-nav-link-disabled-color: rgba(52, 58, 64, 0.75);display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background:none;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width: 1px;--bs-nav-tabs-border-color: #dee2e6;--bs-nav-tabs-border-radius: 0.25rem;--bs-nav-tabs-link-hover-border-color: #e9ecef #e9ecef #dee2e6;--bs-nav-tabs-link-active-color: #000;--bs-nav-tabs-link-active-bg: #fff;--bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #fff;border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1*var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid rgba(0,0,0,0)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1*var(--bs-nav-tabs-border-width))}.nav-pills{--bs-nav-pills-border-radius: 0.25rem;--bs-nav-pills-link-active-color: #fff;--bs-nav-pills-link-active-bg: #2780e3}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap: 1rem;--bs-nav-underline-border-width: 0.125rem;--bs-nav-underline-link-active-color: #000;gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid rgba(0,0,0,0)}.nav-underline .nav-link:hover,.nav-underline .nav-link:focus{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x: 0;--bs-navbar-padding-y: 0.5rem;--bs-navbar-color: #fdfeff;--bs-navbar-hover-color: rgba(253, 253, 255, 0.8);--bs-navbar-disabled-color: rgba(253, 254, 255, 0.75);--bs-navbar-active-color: #fdfdff;--bs-navbar-brand-padding-y: 0.3125rem;--bs-navbar-brand-margin-end: 1rem;--bs-navbar-brand-font-size: 1.25rem;--bs-navbar-brand-color: #fdfeff;--bs-navbar-brand-hover-color: #fdfdff;--bs-navbar-nav-link-padding-x: 0.5rem;--bs-navbar-toggler-padding-y: 0.25;--bs-navbar-toggler-padding-x: 0;--bs-navbar-toggler-font-size: 1.25rem;--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfeff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color: rgba(253, 254, 255, 0);--bs-navbar-toggler-border-radius: 0.25rem;--bs-navbar-toggler-focus-width: 0.25rem;--bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-sm,.navbar>.container-md,.navbar>.container-lg,.navbar>.container-xl,.navbar>.container-xxl{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-brand:hover,.navbar-brand:focus{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x: 0;--bs-nav-link-padding-y: 0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color: var(--bs-navbar-color);--bs-nav-link-hover-color: var(--bs-navbar-hover-color);--bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:hover,.navbar-text a:focus{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:rgba(0,0,0,0);border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);transition:var(--bs-navbar-toggler-transition)}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;-webkit-flex-grow:1;width:auto !important;height:auto !important;visibility:visible !important;background-color:rgba(0,0,0,0) !important;border:0 !important;transform:none !important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color: #fdfeff;--bs-navbar-hover-color: rgba(253, 253, 255, 0.8);--bs-navbar-disabled-color: rgba(253, 254, 255, 0.75);--bs-navbar-active-color: #fdfdff;--bs-navbar-brand-color: #fdfeff;--bs-navbar-brand-hover-color: #fdfdff;--bs-navbar-toggler-border-color: rgba(253, 254, 255, 0);--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfeff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfeff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y: 1rem;--bs-card-spacer-x: 1rem;--bs-card-title-spacer-y: 0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width: 1px;--bs-card-border-color: rgba(0, 0, 0, 0.175);--bs-card-border-radius: 0.25rem;--bs-card-box-shadow: ;--bs-card-inner-border-radius: calc(0.25rem - 1px);--bs-card-cap-padding-y: 0.5rem;--bs-card-cap-padding-x: 1rem;--bs-card-cap-bg: rgba(52, 58, 64, 0.25);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg: #fff;--bs-card-img-overlay-padding: 1rem;--bs-card-group-margin: 0.75rem;position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0}.card>.list-group:last-child{border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-0.5*var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header-tabs{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-bottom:calc(-1*var(--bs-card-cap-padding-y));margin-left:calc(-0.5*var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-0.5*var(--bs-card-cap-padding-x));margin-left:calc(-0.5*var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding)}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}}.accordion{--bs-accordion-color: #343a40;--bs-accordion-bg: #fff;--bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;--bs-accordion-border-color: #dee2e6;--bs-accordion-border-width: 1px;--bs-accordion-border-radius: 0.25rem;--bs-accordion-inner-border-radius: calc(0.25rem - 1px);--bs-accordion-btn-padding-x: 1.25rem;--bs-accordion-btn-padding-y: 1rem;--bs-accordion-btn-color: #343a40;--bs-accordion-btn-bg: #fff;--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23343a40'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width: 1.25rem;--bs-accordion-btn-icon-transform: rotate(-180deg);--bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2310335b'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color: #93c0f1;--bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(39, 128, 227, 0.25);--bs-accordion-body-padding-x: 1.25rem;--bs-accordion-body-padding-y: 1rem;--bs-accordion-active-color: #10335b;--bs-accordion-active-bg: #d4e6f9}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1*var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:not(:first-of-type){border-top:0}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237db3ee'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%237db3ee'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x: 0;--bs-breadcrumb-padding-y: 0;--bs-breadcrumb-margin-bottom: 1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color: rgba(52, 58, 64, 0.75);--bs-breadcrumb-item-padding-x: 0.5rem;--bs-breadcrumb-item-active-color: rgba(52, 58, 64, 0.75);display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x: 0.75rem;--bs-pagination-padding-y: 0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color: #2761e3;--bs-pagination-bg: #fff;--bs-pagination-border-width: 1px;--bs-pagination-border-color: #dee2e6;--bs-pagination-border-radius: 0.25rem;--bs-pagination-hover-color: #1f4eb6;--bs-pagination-hover-bg: #f8f9fa;--bs-pagination-hover-border-color: #dee2e6;--bs-pagination-focus-color: #1f4eb6;--bs-pagination-focus-bg: #e9ecef;--bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(39, 128, 227, 0.25);--bs-pagination-active-color: #fff;--bs-pagination-active-bg: #2780e3;--bs-pagination-active-border-color: #2780e3;--bs-pagination-disabled-color: rgba(52, 58, 64, 0.75);--bs-pagination-disabled-bg: #e9ecef;--bs-pagination-disabled-border-color: #dee2e6;display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.page-link.active,.active>.page-link{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.page-link.disabled,.disabled>.page-link{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(1px*-1)}.pagination-lg{--bs-pagination-padding-x: 1.5rem;--bs-pagination-padding-y: 0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius: 0.5rem}.pagination-sm{--bs-pagination-padding-x: 0.5rem;--bs-pagination-padding-y: 0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius: 0.2em}.badge{--bs-badge-padding-x: 0.65em;--bs-badge-padding-y: 0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight: 700;--bs-badge-color: #fff;--bs-badge-border-radius: 0.25rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg: transparent;--bs-alert-padding-x: 1rem;--bs-alert-padding-y: 1rem;--bs-alert-margin-bottom: 1rem;--bs-alert-color: inherit;--bs-alert-border-color: transparent;--bs-alert-border: 0 solid var(--bs-alert-border-color);--bs-alert-border-radius: 0.25rem;--bs-alert-link-color: inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{--bs-alert-color: var(--bs-default-text-emphasis);--bs-alert-bg: var(--bs-default-bg-subtle);--bs-alert-border-color: var(--bs-default-border-subtle);--bs-alert-link-color: var(--bs-default-text-emphasis)}.alert-primary{--bs-alert-color: var(--bs-primary-text-emphasis);--bs-alert-bg: var(--bs-primary-bg-subtle);--bs-alert-border-color: var(--bs-primary-border-subtle);--bs-alert-link-color: var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color: var(--bs-secondary-text-emphasis);--bs-alert-bg: var(--bs-secondary-bg-subtle);--bs-alert-border-color: var(--bs-secondary-border-subtle);--bs-alert-link-color: var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color: var(--bs-success-text-emphasis);--bs-alert-bg: var(--bs-success-bg-subtle);--bs-alert-border-color: var(--bs-success-border-subtle);--bs-alert-link-color: var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color: var(--bs-info-text-emphasis);--bs-alert-bg: var(--bs-info-bg-subtle);--bs-alert-border-color: var(--bs-info-border-subtle);--bs-alert-link-color: var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color: var(--bs-warning-text-emphasis);--bs-alert-bg: var(--bs-warning-bg-subtle);--bs-alert-border-color: var(--bs-warning-border-subtle);--bs-alert-link-color: var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color: var(--bs-danger-text-emphasis);--bs-alert-bg: var(--bs-danger-bg-subtle);--bs-alert-border-color: var(--bs-danger-border-subtle);--bs-alert-link-color: var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color: var(--bs-light-text-emphasis);--bs-alert-bg: var(--bs-light-bg-subtle);--bs-alert-border-color: var(--bs-light-border-subtle);--bs-alert-link-color: var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color: var(--bs-dark-text-emphasis);--bs-alert-bg: var(--bs-dark-bg-subtle);--bs-alert-border-color: var(--bs-dark-border-subtle);--bs-alert-link-color: var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:.5rem}}.progress,.progress-stacked{--bs-progress-height: 0.5rem;--bs-progress-font-size:0.75rem;--bs-progress-bg: #e9ecef;--bs-progress-border-radius: 0.25rem;--bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-progress-bar-color: #fff;--bs-progress-bar-bg: #2780e3;--bs-progress-bar-transition: width 0.6s ease;display:flex;display:-webkit-flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg)}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{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);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color: #343a40;--bs-list-group-bg: #fff;--bs-list-group-border-color: #dee2e6;--bs-list-group-border-width: 1px;--bs-list-group-border-radius: 0.25rem;--bs-list-group-item-padding-x: 1rem;--bs-list-group-item-padding-y: 0.5rem;--bs-list-group-action-color: rgba(52, 58, 64, 0.75);--bs-list-group-action-hover-color: #000;--bs-list-group-action-hover-bg: #f8f9fa;--bs-list-group-action-active-color: #343a40;--bs-list-group-action-active-bg: #e9ecef;--bs-list-group-disabled-color: rgba(52, 58, 64, 0.75);--bs-list-group-disabled-bg: #fff;--bs-list-group-active-color: #fff;--bs-list-group-active-bg: #2780e3;--bs-list-group-active-border-color: #2780e3;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1*var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1*var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{--bs-list-group-color: var(--bs-default-text-emphasis);--bs-list-group-bg: var(--bs-default-bg-subtle);--bs-list-group-border-color: var(--bs-default-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-default-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-default-border-subtle);--bs-list-group-active-color: var(--bs-default-bg-subtle);--bs-list-group-active-bg: var(--bs-default-text-emphasis);--bs-list-group-active-border-color: var(--bs-default-text-emphasis)}.list-group-item-primary{--bs-list-group-color: var(--bs-primary-text-emphasis);--bs-list-group-bg: var(--bs-primary-bg-subtle);--bs-list-group-border-color: var(--bs-primary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-primary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-primary-border-subtle);--bs-list-group-active-color: var(--bs-primary-bg-subtle);--bs-list-group-active-bg: var(--bs-primary-text-emphasis);--bs-list-group-active-border-color: var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color: var(--bs-secondary-text-emphasis);--bs-list-group-bg: var(--bs-secondary-bg-subtle);--bs-list-group-border-color: var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-secondary-border-subtle);--bs-list-group-active-color: var(--bs-secondary-bg-subtle);--bs-list-group-active-bg: var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color: var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color: var(--bs-success-text-emphasis);--bs-list-group-bg: var(--bs-success-bg-subtle);--bs-list-group-border-color: var(--bs-success-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-success-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-success-border-subtle);--bs-list-group-active-color: var(--bs-success-bg-subtle);--bs-list-group-active-bg: var(--bs-success-text-emphasis);--bs-list-group-active-border-color: var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color: var(--bs-info-text-emphasis);--bs-list-group-bg: var(--bs-info-bg-subtle);--bs-list-group-border-color: var(--bs-info-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-info-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-info-border-subtle);--bs-list-group-active-color: var(--bs-info-bg-subtle);--bs-list-group-active-bg: var(--bs-info-text-emphasis);--bs-list-group-active-border-color: var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color: var(--bs-warning-text-emphasis);--bs-list-group-bg: var(--bs-warning-bg-subtle);--bs-list-group-border-color: var(--bs-warning-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-warning-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-warning-border-subtle);--bs-list-group-active-color: var(--bs-warning-bg-subtle);--bs-list-group-active-bg: var(--bs-warning-text-emphasis);--bs-list-group-active-border-color: var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color: var(--bs-danger-text-emphasis);--bs-list-group-bg: var(--bs-danger-bg-subtle);--bs-list-group-border-color: var(--bs-danger-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-danger-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-danger-border-subtle);--bs-list-group-active-color: var(--bs-danger-bg-subtle);--bs-list-group-active-bg: var(--bs-danger-text-emphasis);--bs-list-group-active-border-color: var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color: var(--bs-light-text-emphasis);--bs-list-group-bg: var(--bs-light-bg-subtle);--bs-list-group-border-color: var(--bs-light-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-light-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-light-border-subtle);--bs-list-group-active-color: var(--bs-light-bg-subtle);--bs-list-group-active-bg: var(--bs-light-text-emphasis);--bs-list-group-active-border-color: var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color: var(--bs-dark-text-emphasis);--bs-list-group-bg: var(--bs-dark-bg-subtle);--bs-list-group-border-color: var(--bs-dark-border-subtle);--bs-list-group-action-hover-color: var(--bs-emphasis-color);--bs-list-group-action-hover-bg: var(--bs-dark-border-subtle);--bs-list-group-action-active-color: var(--bs-emphasis-color);--bs-list-group-action-active-bg: var(--bs-dark-border-subtle);--bs-list-group-active-color: var(--bs-dark-bg-subtle);--bs-list-group-active-bg: var(--bs-dark-text-emphasis);--bs-list-group-active-border-color: var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color: #000;--bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity: 0.5;--bs-btn-close-hover-opacity: 0.75;--bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(39, 128, 227, 0.25);--bs-btn-close-focus-opacity: 1;--bs-btn-close-disabled-opacity: 0.25;--bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:rgba(0,0,0,0) var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex: 1090;--bs-toast-padding-x: 0.75rem;--bs-toast-padding-y: 0.5rem;--bs-toast-spacing: 1.5rem;--bs-toast-max-width: 350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg: rgba(255, 255, 255, 0.85);--bs-toast-border-width: 1px;--bs-toast-border-color: rgba(0, 0, 0, 0.175);--bs-toast-border-radius: 0.25rem;--bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-toast-header-color: rgba(52, 58, 64, 0.75);--bs-toast-header-bg: rgba(255, 255, 255, 0.85);--bs-toast-header-border-color: rgba(0, 0, 0, 0.175);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex: 1090;position:absolute;z-index:var(--bs-toast-zindex);width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color)}.toast-header .btn-close{margin-right:calc(-0.5*var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex: 1055;--bs-modal-width: 500px;--bs-modal-padding: 1rem;--bs-modal-margin: 0.5rem;--bs-modal-color: ;--bs-modal-bg: #fff;--bs-modal-border-color: rgba(0, 0, 0, 0.175);--bs-modal-border-width: 1px;--bs-modal-border-radius: 0.5rem;--bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-modal-inner-border-radius: calc(0.5rem - 1px);--bs-modal-header-padding-x: 1rem;--bs-modal-header-padding-y: 1rem;--bs-modal-header-padding: 1rem 1rem;--bs-modal-header-border-color: #dee2e6;--bs-modal-header-border-width: 1px;--bs-modal-title-line-height: 1.5;--bs-modal-footer-gap: 0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color: #dee2e6;--bs-modal-footer-border-width: 1px;position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin)*2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - var(--bs-modal-margin)*2)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);outline:0}.modal-backdrop{--bs-backdrop-zindex: 1050;--bs-backdrop-bg: #000;--bs-backdrop-opacity: 0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y)*.5) calc(var(--bs-modal-header-padding-x)*.5);margin:calc(-0.5*var(--bs-modal-header-padding-y)) calc(-0.5*var(--bs-modal-header-padding-x)) calc(-0.5*var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap)*.5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap)*.5)}@media(min-width: 576px){.modal{--bs-modal-margin: 1.75rem;--bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width: 300px}}@media(min-width: 992px){.modal-lg,.modal-xl{--bs-modal-width: 800px}}@media(min-width: 1200px){.modal-xl{--bs-modal-width: 1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex: 1080;--bs-tooltip-max-width: 200px;--bs-tooltip-padding-x: 0.5rem;--bs-tooltip-padding-y: 0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color: #fff;--bs-tooltip-bg: #000;--bs-tooltip-border-radius: 0.25rem;--bs-tooltip-opacity: 0.9;--bs-tooltip-arrow-width: 0.8rem;--bs-tooltip-arrow-height: 0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width)*.5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:calc(-1*var(--bs-tooltip-arrow-height))}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:calc(-1*var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width)*.5) 0 calc(var(--bs-tooltip-arrow-width)*.5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg)}.popover{--bs-popover-zindex: 1070;--bs-popover-max-width: 276px;--bs-popover-font-size:0.875rem;--bs-popover-bg: #fff;--bs-popover-border-width: 1px;--bs-popover-border-color: rgba(0, 0, 0, 0.175);--bs-popover-border-radius: 0.5rem;--bs-popover-inner-border-radius: calc(0.5rem - 1px);--bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-popover-header-padding-x: 1rem;--bs-popover-header-padding-y: 0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: inherit;--bs-popover-header-bg: #e9ecef;--bs-popover-body-padding-x: 1rem;--bs-popover-body-padding-y: 1rem;--bs-popover-body-color: #343a40;--bs-popover-arrow-width: 1rem;--bs-popover-arrow-height: 0.5rem;--bs-popover-arrow-border: var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid;border-width:0}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width)*.5) 0}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{border-width:0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-0.5*var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-1*(var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{border-width:calc(var(--bs-popover-arrow-width)*.5) 0 calc(var(--bs-popover-arrow-width)*.5) var(--bs-popover-arrow-height)}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid rgba(0,0,0,0);border-bottom:10px solid rgba(0,0,0,0);opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-prev-icon,[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark].carousel .carousel-control-prev-icon,[data-bs-theme=dark].carousel .carousel-control-next-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target],[data-bs-theme=dark].carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption,[data-bs-theme=dark].carousel .carousel-caption{color:#000}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-border-width: 0.25em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:rgba(0,0,0,0)}.spinner-border-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem;--bs-spinner-border-width: 0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width: 2rem;--bs-spinner-height: 2rem;--bs-spinner-vertical-align: -0.125em;--bs-spinner-animation-speed: 0.75s;--bs-spinner-animation-name: spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width: 1rem;--bs-spinner-height: 1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed: 1.5s}}.offcanvas,.offcanvas-xxl,.offcanvas-xl,.offcanvas-lg,.offcanvas-md,.offcanvas-sm{--bs-offcanvas-zindex: 1045;--bs-offcanvas-width: 400px;--bs-offcanvas-height: 30vh;--bs-offcanvas-padding-x: 1rem;--bs-offcanvas-padding-y: 1rem;--bs-offcanvas-color: #343a40;--bs-offcanvas-bg: #fff;--bs-offcanvas-border-width: 1px;--bs-offcanvas-border-color: rgba(0, 0, 0, 0.175);--bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-offcanvas-transition: transform 0.3s ease-in-out;--bs-offcanvas-title-line-height: 1.5}@media(max-width: 575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 575.98px)and (prefers-reduced-motion: reduce){.offcanvas-sm{transition:none}}@media(max-width: 575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.showing,.offcanvas-sm.show:not(.hiding){transform:none}.offcanvas-sm.showing,.offcanvas-sm.hiding,.offcanvas-sm.show{visibility:visible}}@media(min-width: 576px){.offcanvas-sm{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 767.98px)and (prefers-reduced-motion: reduce){.offcanvas-md{transition:none}}@media(max-width: 767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.showing,.offcanvas-md.show:not(.hiding){transform:none}.offcanvas-md.showing,.offcanvas-md.hiding,.offcanvas-md.show{visibility:visible}}@media(min-width: 768px){.offcanvas-md{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 991.98px)and (prefers-reduced-motion: reduce){.offcanvas-lg{transition:none}}@media(max-width: 991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.showing,.offcanvas-lg.show:not(.hiding){transform:none}.offcanvas-lg.showing,.offcanvas-lg.hiding,.offcanvas-lg.show{visibility:visible}}@media(min-width: 992px){.offcanvas-lg{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1199.98px)and (prefers-reduced-motion: reduce){.offcanvas-xl{transition:none}}@media(max-width: 1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.showing,.offcanvas-xl.show:not(.hiding){transform:none}.offcanvas-xl.showing,.offcanvas-xl.hiding,.offcanvas-xl.show{visibility:visible}}@media(min-width: 1200px){.offcanvas-xl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}@media(max-width: 1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media(max-width: 1399.98px)and (prefers-reduced-motion: reduce){.offcanvas-xxl{transition:none}}@media(max-width: 1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.showing,.offcanvas-xxl.show:not(.hiding){transform:none}.offcanvas-xxl.showing,.offcanvas-xxl.hiding,.offcanvas-xxl.show{visibility:visible}}@media(min-width: 1400px){.offcanvas-xxl{--bs-offcanvas-height: auto;--bs-offcanvas-border-width: 0;background-color:rgba(0,0,0,0) !important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible;background-color:rgba(0,0,0,0) !important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.showing,.offcanvas.show:not(.hiding){transform:none}.offcanvas.showing,.offcanvas.hiding,.offcanvas.show{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y)*.5) calc(var(--bs-offcanvas-padding-x)*.5);margin-top:calc(-0.5*var(--bs-offcanvas-padding-y));margin-right:calc(-0.5*var(--bs-offcanvas-padding-x));margin-bottom:calc(-0.5*var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-default{color:#fff !important;background-color:RGBA(var(--bs-default-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-primary{color:#fff !important;background-color:RGBA(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-secondary{color:#fff !important;background-color:RGBA(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-success{color:#fff !important;background-color:RGBA(var(--bs-success-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-info{color:#fff !important;background-color:RGBA(var(--bs-info-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-warning{color:#fff !important;background-color:RGBA(var(--bs-warning-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-danger{color:#fff !important;background-color:RGBA(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-light{color:#000 !important;background-color:RGBA(var(--bs-light-rgb), var(--bs-bg-opacity, 1)) !important}.text-bg-dark{color:#fff !important;background-color:RGBA(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)) !important}.link-default{color:RGBA(var(--bs-default-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-default-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-default:hover,.link-default:focus{color:RGBA(42, 46, 51, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(42, 46, 51, var(--bs-link-underline-opacity, 1)) !important}.link-primary{color:RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-primary:hover,.link-primary:focus{color:RGBA(31, 102, 182, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(31, 102, 182, var(--bs-link-underline-opacity, 1)) !important}.link-secondary{color:RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-secondary:hover,.link-secondary:focus{color:RGBA(42, 46, 51, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(42, 46, 51, var(--bs-link-underline-opacity, 1)) !important}.link-success{color:RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-success:hover,.link-success:focus{color:RGBA(50, 146, 19, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(50, 146, 19, var(--bs-link-underline-opacity, 1)) !important}.link-info{color:RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-info:hover,.link-info:focus{color:RGBA(122, 67, 150, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(122, 67, 150, var(--bs-link-underline-opacity, 1)) !important}.link-warning{color:RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-warning:hover,.link-warning:focus{color:RGBA(204, 94, 19, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(204, 94, 19, var(--bs-link-underline-opacity, 1)) !important}.link-danger{color:RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-danger:hover,.link-danger:focus{color:RGBA(204, 0, 46, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(204, 0, 46, var(--bs-link-underline-opacity, 1)) !important}.link-light{color:RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-light:hover,.link-light:focus{color:RGBA(249, 250, 251, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important}.link-dark{color:RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-dark:hover,.link-dark:focus{color:RGBA(42, 46, 51, var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(42, 46, 51, var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-body-emphasis:hover,.link-body-emphasis:focus{color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-align-items:center;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));text-underline-offset:.25em;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;-webkit-flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media(prefers-reduced-motion: reduce){.icon-link>.bi{transition:none}}.icon-link-hover:hover>.bi,.icon-link-hover:focus-visible>.bi{transform:var(--bs-icon-link-transform, translate3d(0.25em, 0, 0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: 75%}.ratio-16x9{--bs-aspect-ratio: 56.25%}.ratio-21x9{--bs-aspect-ratio: 42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.sticky-bottom{position:sticky;bottom:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:sticky;bottom:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.visually-hidden:not(caption),.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption){position:absolute !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.object-fit-contain{object-fit:contain !important}.object-fit-cover{object-fit:cover !important}.object-fit-fill{object-fit:fill !important}.object-fit-scale{object-fit:scale-down !important}.object-fit-none{object-fit:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.overflow-x-auto{overflow-x:auto !important}.overflow-x-hidden{overflow-x:hidden !important}.overflow-x-visible{overflow-x:visible !important}.overflow-x-scroll{overflow-x:scroll !important}.overflow-y-auto{overflow-y:auto !important}.overflow-y-hidden{overflow-y:hidden !important}.overflow-y-visible{overflow-y:visible !important}.overflow-y-scroll{overflow-y:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-inline-grid{display:inline-grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.focus-ring-default{--bs-focus-ring-color: rgba(var(--bs-default-rgb), var(--bs-focus-ring-opacity))}.focus-ring-primary{--bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-0{border:0 !important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-top-0{border-top:0 !important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important}.border-start-0{border-left:0 !important}.border-default{--bs-border-opacity: 1;border-color:rgba(var(--bs-default-rgb), var(--bs-border-opacity)) !important}.border-primary{--bs-border-opacity: 1;border-color:rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important}.border-secondary{--bs-border-opacity: 1;border-color:rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important}.border-success{--bs-border-opacity: 1;border-color:rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important}.border-info{--bs-border-opacity: 1;border-color:rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important}.border-warning{--bs-border-opacity: 1;border-color:rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important}.border-danger{--bs-border-opacity: 1;border-color:rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important}.border-light{--bs-border-opacity: 1;border-color:rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important}.border-dark{--bs-border-opacity: 1;border-color:rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important}.border-black{--bs-border-opacity: 1;border-color:rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important}.border-white{--bs-border-opacity: 1;border-color:rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle) !important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle) !important}.border-success-subtle{border-color:var(--bs-success-border-subtle) !important}.border-info-subtle{border-color:var(--bs-info-border-subtle) !important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle) !important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle) !important}.border-light-subtle{border-color:var(--bs-light-border-subtle) !important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle) !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.border-opacity-10{--bs-border-opacity: 0.1}.border-opacity-25{--bs-border-opacity: 0.25}.border-opacity-50{--bs-border-opacity: 0.5}.border-opacity-75{--bs-border-opacity: 0.75}.border-opacity-100{--bs-border-opacity: 1}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.row-gap-0{row-gap:0 !important}.row-gap-1{row-gap:.25rem !important}.row-gap-2{row-gap:.5rem !important}.row-gap-3{row-gap:1rem !important}.row-gap-4{row-gap:1.5rem !important}.row-gap-5{row-gap:3rem !important}.column-gap-0{column-gap:0 !important}.column-gap-1{column-gap:.25rem !important}.column-gap-2{column-gap:.5rem !important}.column-gap-3{column-gap:1rem !important}.column-gap-4{column-gap:1.5rem !important}.column-gap-5{column-gap:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.325rem + 0.9vw) !important}.fs-2{font-size:calc(1.29rem + 0.48vw) !important}.fs-3{font-size:calc(1.27rem + 0.24vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-lighter{font-weight:lighter !important}.fw-light{font-weight:300 !important}.fw-normal{font-weight:400 !important}.fw-medium{font-weight:500 !important}.fw-semibold{font-weight:600 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !important}.text-body-secondary{--bs-text-opacity: 1;color:var(--bs-secondary-color) !important}.text-body-tertiary{--bs-text-opacity: 1;color:var(--bs-tertiary-color) !important}.text-body-emphasis{--bs-text-opacity: 1;color:var(--bs-emphasis-color) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis) !important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis) !important}.text-success-emphasis{color:var(--bs-success-text-emphasis) !important}.text-info-emphasis{color:var(--bs-info-text-emphasis) !important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis) !important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis) !important}.text-light-emphasis{color:var(--bs-light-text-emphasis) !important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis) !important}.link-opacity-10{--bs-link-opacity: 0.1}.link-opacity-10-hover:hover{--bs-link-opacity: 0.1}.link-opacity-25{--bs-link-opacity: 0.25}.link-opacity-25-hover:hover{--bs-link-opacity: 0.25}.link-opacity-50{--bs-link-opacity: 0.5}.link-opacity-50-hover:hover{--bs-link-opacity: 0.5}.link-opacity-75{--bs-link-opacity: 0.75}.link-opacity-75-hover:hover{--bs-link-opacity: 0.75}.link-opacity-100{--bs-link-opacity: 1}.link-opacity-100-hover:hover{--bs-link-opacity: 1}.link-offset-1{text-underline-offset:.125em !important}.link-offset-1-hover:hover{text-underline-offset:.125em !important}.link-offset-2{text-underline-offset:.25em !important}.link-offset-2-hover:hover{text-underline-offset:.25em !important}.link-offset-3{text-underline-offset:.375em !important}.link-offset-3-hover:hover{text-underline-offset:.375em !important}.link-underline-default{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-default-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-primary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-secondary{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-success{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-info{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-warning{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-danger{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-light{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important}.link-underline-dark{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important}.link-underline{--bs-link-underline-opacity: 1;text-decoration-color:rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important}.link-underline-opacity-0{--bs-link-underline-opacity: 0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity: 0}.link-underline-opacity-10{--bs-link-underline-opacity: 0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity: 0.1}.link-underline-opacity-25{--bs-link-underline-opacity: 0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity: 0.25}.link-underline-opacity-50{--bs-link-underline-opacity: 0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity: 0.5}.link-underline-opacity-75{--bs-link-underline-opacity: 0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity: 0.75}.link-underline-opacity-100{--bs-link-underline-opacity: 1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-body-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-body-tertiary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle) !important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle) !important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle) !important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle) !important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle) !important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle) !important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle) !important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle) !important}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:var(--bs-border-radius) !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:var(--bs-border-radius-sm) !important}.rounded-2{border-radius:var(--bs-border-radius) !important}.rounded-3{border-radius:var(--bs-border-radius-lg) !important}.rounded-4{border-radius:var(--bs-border-radius-xl) !important}.rounded-5{border-radius:var(--bs-border-radius-xxl) !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:var(--bs-border-radius-pill) !important}.rounded-top{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-0{border-top-left-radius:0 !important;border-top-right-radius:0 !important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm) !important;border-top-right-radius:var(--bs-border-radius-sm) !important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius) !important;border-top-right-radius:var(--bs-border-radius) !important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg) !important;border-top-right-radius:var(--bs-border-radius-lg) !important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl) !important;border-top-right-radius:var(--bs-border-radius-xl) !important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl) !important;border-top-right-radius:var(--bs-border-radius-xxl) !important}.rounded-top-circle{border-top-left-radius:50% !important;border-top-right-radius:50% !important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill) !important;border-top-right-radius:var(--bs-border-radius-pill) !important}.rounded-end{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-0{border-top-right-radius:0 !important;border-bottom-right-radius:0 !important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm) !important;border-bottom-right-radius:var(--bs-border-radius-sm) !important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius) !important;border-bottom-right-radius:var(--bs-border-radius) !important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg) !important;border-bottom-right-radius:var(--bs-border-radius-lg) !important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl) !important;border-bottom-right-radius:var(--bs-border-radius-xl) !important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-right-radius:var(--bs-border-radius-xxl) !important}.rounded-end-circle{border-top-right-radius:50% !important;border-bottom-right-radius:50% !important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill) !important;border-bottom-right-radius:var(--bs-border-radius-pill) !important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-0{border-bottom-right-radius:0 !important;border-bottom-left-radius:0 !important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm) !important;border-bottom-left-radius:var(--bs-border-radius-sm) !important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius) !important;border-bottom-left-radius:var(--bs-border-radius) !important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg) !important;border-bottom-left-radius:var(--bs-border-radius-lg) !important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl) !important;border-bottom-left-radius:var(--bs-border-radius-xl) !important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl) !important;border-bottom-left-radius:var(--bs-border-radius-xxl) !important}.rounded-bottom-circle{border-bottom-right-radius:50% !important;border-bottom-left-radius:50% !important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill) !important;border-bottom-left-radius:var(--bs-border-radius-pill) !important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-0{border-bottom-left-radius:0 !important;border-top-left-radius:0 !important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm) !important;border-top-left-radius:var(--bs-border-radius-sm) !important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius) !important;border-top-left-radius:var(--bs-border-radius) !important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg) !important;border-top-left-radius:var(--bs-border-radius-lg) !important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl) !important;border-top-left-radius:var(--bs-border-radius-xl) !important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl) !important;border-top-left-radius:var(--bs-border-radius-xxl) !important}.rounded-start-circle{border-bottom-left-radius:50% !important;border-top-left-radius:50% !important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill) !important;border-top-left-radius:var(--bs-border-radius-pill) !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}.z-n1{z-index:-1 !important}.z-0{z-index:0 !important}.z-1{z-index:1 !important}.z-2{z-index:2 !important}.z-3{z-index:3 !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.object-fit-sm-contain{object-fit:contain !important}.object-fit-sm-cover{object-fit:cover !important}.object-fit-sm-fill{object-fit:fill !important}.object-fit-sm-scale{object-fit:scale-down !important}.object-fit-sm-none{object-fit:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-inline-grid{display:inline-grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.row-gap-sm-0{row-gap:0 !important}.row-gap-sm-1{row-gap:.25rem !important}.row-gap-sm-2{row-gap:.5rem !important}.row-gap-sm-3{row-gap:1rem !important}.row-gap-sm-4{row-gap:1.5rem !important}.row-gap-sm-5{row-gap:3rem !important}.column-gap-sm-0{column-gap:0 !important}.column-gap-sm-1{column-gap:.25rem !important}.column-gap-sm-2{column-gap:.5rem !important}.column-gap-sm-3{column-gap:1rem !important}.column-gap-sm-4{column-gap:1.5rem !important}.column-gap-sm-5{column-gap:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.object-fit-md-contain{object-fit:contain !important}.object-fit-md-cover{object-fit:cover !important}.object-fit-md-fill{object-fit:fill !important}.object-fit-md-scale{object-fit:scale-down !important}.object-fit-md-none{object-fit:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-inline-grid{display:inline-grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.row-gap-md-0{row-gap:0 !important}.row-gap-md-1{row-gap:.25rem !important}.row-gap-md-2{row-gap:.5rem !important}.row-gap-md-3{row-gap:1rem !important}.row-gap-md-4{row-gap:1.5rem !important}.row-gap-md-5{row-gap:3rem !important}.column-gap-md-0{column-gap:0 !important}.column-gap-md-1{column-gap:.25rem !important}.column-gap-md-2{column-gap:.5rem !important}.column-gap-md-3{column-gap:1rem !important}.column-gap-md-4{column-gap:1.5rem !important}.column-gap-md-5{column-gap:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.object-fit-lg-contain{object-fit:contain !important}.object-fit-lg-cover{object-fit:cover !important}.object-fit-lg-fill{object-fit:fill !important}.object-fit-lg-scale{object-fit:scale-down !important}.object-fit-lg-none{object-fit:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-inline-grid{display:inline-grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.row-gap-lg-0{row-gap:0 !important}.row-gap-lg-1{row-gap:.25rem !important}.row-gap-lg-2{row-gap:.5rem !important}.row-gap-lg-3{row-gap:1rem !important}.row-gap-lg-4{row-gap:1.5rem !important}.row-gap-lg-5{row-gap:3rem !important}.column-gap-lg-0{column-gap:0 !important}.column-gap-lg-1{column-gap:.25rem !important}.column-gap-lg-2{column-gap:.5rem !important}.column-gap-lg-3{column-gap:1rem !important}.column-gap-lg-4{column-gap:1.5rem !important}.column-gap-lg-5{column-gap:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.object-fit-xl-contain{object-fit:contain !important}.object-fit-xl-cover{object-fit:cover !important}.object-fit-xl-fill{object-fit:fill !important}.object-fit-xl-scale{object-fit:scale-down !important}.object-fit-xl-none{object-fit:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-inline-grid{display:inline-grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.row-gap-xl-0{row-gap:0 !important}.row-gap-xl-1{row-gap:.25rem !important}.row-gap-xl-2{row-gap:.5rem !important}.row-gap-xl-3{row-gap:1rem !important}.row-gap-xl-4{row-gap:1.5rem !important}.row-gap-xl-5{row-gap:3rem !important}.column-gap-xl-0{column-gap:0 !important}.column-gap-xl-1{column-gap:.25rem !important}.column-gap-xl-2{column-gap:.5rem !important}.column-gap-xl-3{column-gap:1rem !important}.column-gap-xl-4{column-gap:1.5rem !important}.column-gap-xl-5{column-gap:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.object-fit-xxl-contain{object-fit:contain !important}.object-fit-xxl-cover{object-fit:cover !important}.object-fit-xxl-fill{object-fit:fill !important}.object-fit-xxl-scale{object-fit:scale-down !important}.object-fit-xxl-none{object-fit:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-inline-grid{display:inline-grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.row-gap-xxl-0{row-gap:0 !important}.row-gap-xxl-1{row-gap:.25rem !important}.row-gap-xxl-2{row-gap:.5rem !important}.row-gap-xxl-3{row-gap:1rem !important}.row-gap-xxl-4{row-gap:1.5rem !important}.row-gap-xxl-5{row-gap:3rem !important}.column-gap-xxl-0{column-gap:0 !important}.column-gap-xxl-1{column-gap:.25rem !important}.column-gap-xxl-2{column-gap:.5rem !important}.column-gap-xxl-3{column-gap:1rem !important}.column-gap-xxl-4{column-gap:1.5rem !important}.column-gap-xxl-5{column-gap:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#fff}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#fff}.bg-warning{color:#fff}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2rem !important}.fs-2{font-size:1.65rem !important}.fs-3{font-size:1.45rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-inline-grid{display:inline-grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.bg-blue{--bslib-color-bg: #2780e3;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #2780e3;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #613d7c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #613d7c;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #e83e8c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #e83e8c;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #ff0039;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #ff0039;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #f0ad4e;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #f0ad4e;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #ff7518;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #ff7518;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #3fb618;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #3fb618;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #9954bb;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #9954bb;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #343a40}.bg-default{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.text-primary{--bslib-color-fg: #2780e3}.bg-primary{--bslib-color-bg: #2780e3;--bslib-color-fg: #fff}.text-secondary{--bslib-color-fg: #343a40}.bg-secondary{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.text-success{--bslib-color-fg: #3fb618}.bg-success{--bslib-color-bg: #3fb618;--bslib-color-fg: #fff}.text-info{--bslib-color-fg: #9954bb}.bg-info{--bslib-color-bg: #9954bb;--bslib-color-fg: #fff}.text-warning{--bslib-color-fg: #ff7518}.bg-warning{--bslib-color-bg: #ff7518;--bslib-color-fg: #fff}.text-danger{--bslib-color-fg: #ff0039}.bg-danger{--bslib-color-bg: #ff0039;--bslib-color-fg: #fff}.text-light{--bslib-color-fg: #f8f9fa}.bg-light{--bslib-color-bg: #f8f9fa;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #343a40}.bg-dark{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.bg-gradient-blue-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #4053e9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #4053e9;color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #fff;--bslib-color-bg: #3e65ba;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #3e65ba;color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #fff;--bslib-color-bg: #7466c0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #7466c0;color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #fff;--bslib-color-bg: #7d4d9f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #7d4d9f;color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #fff;--bslib-color-bg: #7792a7;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #7792a7;color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #7d7c92;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #7d7c92;color:#fff}.bg-gradient-blue-green{--bslib-color-fg: #fff;--bslib-color-bg: #319692;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #319692;color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #fff;--bslib-color-bg: #249dc5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #249dc5;color:#fff}.bg-gradient-blue-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #556ed3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #556ed3;color:#fff}.bg-gradient-indigo-blue{--bslib-color-fg: #fff;--bslib-color-bg: #4d3dec;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #4d3dec;color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #fff;--bslib-color-bg: #6422c3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #6422c3;color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #fff;--bslib-color-bg: #9a22c9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #9a22c9;color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #fff;--bslib-color-bg: #a30aa8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #a30aa8;color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #fff;--bslib-color-bg: #9d4fb0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #9d4fb0;color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #a3389b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #a3389b;color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #fff;--bslib-color-bg: #56529b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #56529b;color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #fff;--bslib-color-bg: #4a5ace;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4a5ace;color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #7a2bdc;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #7a2bdc;color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #fff;--bslib-color-bg: #4a58a5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #4a58a5;color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #632bab;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #632bab;color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #fff;--bslib-color-bg: #973d82;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #973d82;color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #fff;--bslib-color-bg: #a02561;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #a02561;color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #fff;--bslib-color-bg: #9a6a6a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #9a6a6a;color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #a05354;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #a05354;color:#fff}.bg-gradient-purple-green{--bslib-color-fg: #fff;--bslib-color-bg: #536d54;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #536d54;color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #fff;--bslib-color-bg: #477587;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #477587;color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #774695;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #774695;color:#fff}.bg-gradient-pink-blue{--bslib-color-fg: #fff;--bslib-color-bg: #9b58af;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #9b58af;color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #b42cb5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #b42cb5;color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #fff;--bslib-color-bg: #b23e86;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #b23e86;color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #fff;--bslib-color-bg: #f1256b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #f1256b;color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #fff;--bslib-color-bg: #eb6a73;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #eb6a73;color:#fff}.bg-gradient-pink-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #f1545e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #f1545e;color:#fff}.bg-gradient-pink-green{--bslib-color-fg: #fff;--bslib-color-bg: #a46e5e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #a46e5e;color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #fff;--bslib-color-bg: #987690;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #987690;color:#fff}.bg-gradient-pink-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #c8479f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #c8479f;color:#fff}.bg-gradient-red-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a9337d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a9337d;color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #c20683;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c20683;color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #fff;--bslib-color-bg: #c01854;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #c01854;color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #fff;--bslib-color-bg: #f6195a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #f6195a;color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #fff;--bslib-color-bg: #f94541;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #f94541;color:#fff}.bg-gradient-red-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #ff2f2c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #ff2f2c;color:#fff}.bg-gradient-red-green{--bslib-color-fg: #fff;--bslib-color-bg: #b2492c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #b2492c;color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #fff;--bslib-color-bg: #a6505f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6505f;color:#fff}.bg-gradient-red-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #d6226d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #d6226d;color:#fff}.bg-gradient-orange-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a09b8a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a09b8a;color:#fff}.bg-gradient-orange-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #b96e90;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #b96e90;color:#fff}.bg-gradient-orange-purple{--bslib-color-fg: #fff;--bslib-color-bg: #b78060;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #b78060;color:#fff}.bg-gradient-orange-pink{--bslib-color-fg: #fff;--bslib-color-bg: #ed8167;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #ed8167;color:#fff}.bg-gradient-orange-red{--bslib-color-fg: #fff;--bslib-color-bg: #f66846;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #f66846;color:#fff}.bg-gradient-orange-yellow{--bslib-color-fg: #000;--bslib-color-bg: #f69738;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #f69738;color:#000}.bg-gradient-orange-green{--bslib-color-fg: #000;--bslib-color-bg: #a9b138;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #a9b138;color:#000}.bg-gradient-orange-teal{--bslib-color-fg: #000;--bslib-color-bg: #9db86b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #9db86b;color:#000}.bg-gradient-orange-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #cd897a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #cd897a;color:#fff}.bg-gradient-yellow-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a97969;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a97969;color:#fff}.bg-gradient-yellow-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #c24d6f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c24d6f;color:#fff}.bg-gradient-yellow-purple{--bslib-color-fg: #fff;--bslib-color-bg: #c05f40;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #c05f40;color:#fff}.bg-gradient-yellow-pink{--bslib-color-fg: #fff;--bslib-color-bg: #f65f46;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #f65f46;color:#fff}.bg-gradient-yellow-red{--bslib-color-fg: #fff;--bslib-color-bg: #ff4625;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #ff4625;color:#fff}.bg-gradient-yellow-orange{--bslib-color-fg: #000;--bslib-color-bg: #f98b2e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #f98b2e;color:#000}.bg-gradient-yellow-green{--bslib-color-fg: #fff;--bslib-color-bg: #b28f18;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #b28f18;color:#fff}.bg-gradient-yellow-teal{--bslib-color-fg: #fff;--bslib-color-bg: #a6974b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6974b;color:#fff}.bg-gradient-yellow-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #d66859;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #d66859;color:#fff}.bg-gradient-green-blue{--bslib-color-fg: #fff;--bslib-color-bg: #35a069;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #35a069;color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #4f746f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #4f746f;color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #fff;--bslib-color-bg: #4d8640;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #4d8640;color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #fff;--bslib-color-bg: #838646;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #838646;color:#fff}.bg-gradient-green-red{--bslib-color-fg: #fff;--bslib-color-bg: #8c6d25;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #8c6d25;color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #000;--bslib-color-bg: #86b22e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #86b22e;color:#000}.bg-gradient-green-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #8c9c18;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #8c9c18;color:#fff}.bg-gradient-green-teal{--bslib-color-fg: #000;--bslib-color-bg: #33be4b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #33be4b;color:#000}.bg-gradient-green-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #638f59;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #638f59;color:#fff}.bg-gradient-teal-blue{--bslib-color-fg: #fff;--bslib-color-bg: #23acb5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #23acb5;color:#fff}.bg-gradient-teal-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #3c7fbb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3c7fbb;color:#fff}.bg-gradient-teal-purple{--bslib-color-fg: #fff;--bslib-color-bg: #3a918c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #3a918c;color:#fff}.bg-gradient-teal-pink{--bslib-color-fg: #fff;--bslib-color-bg: #709193;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #709193;color:#fff}.bg-gradient-teal-red{--bslib-color-fg: #fff;--bslib-color-bg: #797971;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #797971;color:#fff}.bg-gradient-teal-orange{--bslib-color-fg: #000;--bslib-color-bg: #73be7a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #73be7a;color:#000}.bg-gradient-teal-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #79a764;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #79a764;color:#fff}.bg-gradient-teal-green{--bslib-color-fg: #000;--bslib-color-bg: #2cc164;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #2cc164;color:#000}.bg-gradient-teal-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #509aa5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #509aa5;color:#fff}.bg-gradient-cyan-blue{--bslib-color-fg: #fff;--bslib-color-bg: #6b66cb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #6b66cb;color:#fff}.bg-gradient-cyan-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #8539d1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #8539d1;color:#fff}.bg-gradient-cyan-purple{--bslib-color-fg: #fff;--bslib-color-bg: #834ba2;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #834ba2;color:#fff}.bg-gradient-cyan-pink{--bslib-color-fg: #fff;--bslib-color-bg: #b94ba8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #b94ba8;color:#fff}.bg-gradient-cyan-red{--bslib-color-fg: #fff;--bslib-color-bg: #c23287;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #c23287;color:#fff}.bg-gradient-cyan-orange{--bslib-color-fg: #fff;--bslib-color-bg: #bc788f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #bc788f;color:#fff}.bg-gradient-cyan-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #c2617a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #c2617a;color:#fff}.bg-gradient-cyan-green{--bslib-color-fg: #fff;--bslib-color-bg: #757b7a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #757b7a;color:#fff}.bg-gradient-cyan-teal{--bslib-color-fg: #fff;--bslib-color-bg: #6983ad;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #6983ad;color:#fff}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}:root{--bslib-spacer: 1rem;--bslib-mb-spacer: var(--bslib-spacer, 1rem)}.bslib-mb-spacing{margin-bottom:var(--bslib-mb-spacer)}.bslib-gap-spacing{gap:var(--bslib-mb-spacer)}.bslib-gap-spacing>.bslib-mb-spacing,.bslib-gap-spacing>.form-group,.bslib-gap-spacing>p,.bslib-gap-spacing>pre{margin-bottom:0}.html-fill-container>.html-fill-item.bslib-mb-spacing{margin-bottom:0}.tab-content>.tab-pane.html-fill-container{display:none}.tab-content>.active.html-fill-container{display:flex}.tab-content.html-fill-container{padding:0}.bg-blue{--bslib-color-bg: #2780e3;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-blue{--bslib-color-fg: #2780e3;color:var(--bslib-color-fg)}.bg-indigo{--bslib-color-bg: #6610f2;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-indigo{--bslib-color-fg: #6610f2;color:var(--bslib-color-fg)}.bg-purple{--bslib-color-bg: #613d7c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-purple{--bslib-color-fg: #613d7c;color:var(--bslib-color-fg)}.bg-pink{--bslib-color-bg: #e83e8c;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-pink{--bslib-color-fg: #e83e8c;color:var(--bslib-color-fg)}.bg-red{--bslib-color-bg: #ff0039;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-red{--bslib-color-fg: #ff0039;color:var(--bslib-color-fg)}.bg-orange{--bslib-color-bg: #f0ad4e;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-orange{--bslib-color-fg: #f0ad4e;color:var(--bslib-color-fg)}.bg-yellow{--bslib-color-bg: #ff7518;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-yellow{--bslib-color-fg: #ff7518;color:var(--bslib-color-fg)}.bg-green{--bslib-color-bg: #3fb618;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-green{--bslib-color-fg: #3fb618;color:var(--bslib-color-fg)}.bg-teal{--bslib-color-bg: #20c997;--bslib-color-fg: #000;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-teal{--bslib-color-fg: #20c997;color:var(--bslib-color-fg)}.bg-cyan{--bslib-color-bg: #9954bb;--bslib-color-fg: #fff;background-color:var(--bslib-color-bg);color:var(--bslib-color-fg)}.text-cyan{--bslib-color-fg: #9954bb;color:var(--bslib-color-fg)}.text-default{--bslib-color-fg: #343a40}.bg-default{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.text-primary{--bslib-color-fg: #2780e3}.bg-primary{--bslib-color-bg: #2780e3;--bslib-color-fg: #fff}.text-secondary{--bslib-color-fg: #343a40}.bg-secondary{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.text-success{--bslib-color-fg: #3fb618}.bg-success{--bslib-color-bg: #3fb618;--bslib-color-fg: #fff}.text-info{--bslib-color-fg: #9954bb}.bg-info{--bslib-color-bg: #9954bb;--bslib-color-fg: #fff}.text-warning{--bslib-color-fg: #ff7518}.bg-warning{--bslib-color-bg: #ff7518;--bslib-color-fg: #fff}.text-danger{--bslib-color-fg: #ff0039}.bg-danger{--bslib-color-bg: #ff0039;--bslib-color-fg: #fff}.text-light{--bslib-color-fg: #f8f9fa}.bg-light{--bslib-color-bg: #f8f9fa;--bslib-color-fg: #000}.text-dark{--bslib-color-fg: #343a40}.bg-dark{--bslib-color-bg: #343a40;--bslib-color-fg: #fff}.bg-gradient-blue-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #4053e9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #4053e9;color:#fff}.bg-gradient-blue-purple{--bslib-color-fg: #fff;--bslib-color-bg: #3e65ba;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #3e65ba;color:#fff}.bg-gradient-blue-pink{--bslib-color-fg: #fff;--bslib-color-bg: #7466c0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #7466c0;color:#fff}.bg-gradient-blue-red{--bslib-color-fg: #fff;--bslib-color-bg: #7d4d9f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #7d4d9f;color:#fff}.bg-gradient-blue-orange{--bslib-color-fg: #fff;--bslib-color-bg: #7792a7;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #7792a7;color:#fff}.bg-gradient-blue-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #7d7c92;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #7d7c92;color:#fff}.bg-gradient-blue-green{--bslib-color-fg: #fff;--bslib-color-bg: #319692;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #319692;color:#fff}.bg-gradient-blue-teal{--bslib-color-fg: #fff;--bslib-color-bg: #249dc5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #249dc5;color:#fff}.bg-gradient-blue-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #556ed3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #2780e3 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #556ed3;color:#fff}.bg-gradient-indigo-blue{--bslib-color-fg: #fff;--bslib-color-bg: #4d3dec;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #4d3dec;color:#fff}.bg-gradient-indigo-purple{--bslib-color-fg: #fff;--bslib-color-bg: #6422c3;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #6422c3;color:#fff}.bg-gradient-indigo-pink{--bslib-color-fg: #fff;--bslib-color-bg: #9a22c9;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #9a22c9;color:#fff}.bg-gradient-indigo-red{--bslib-color-fg: #fff;--bslib-color-bg: #a30aa8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #a30aa8;color:#fff}.bg-gradient-indigo-orange{--bslib-color-fg: #fff;--bslib-color-bg: #9d4fb0;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #9d4fb0;color:#fff}.bg-gradient-indigo-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #a3389b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #a3389b;color:#fff}.bg-gradient-indigo-green{--bslib-color-fg: #fff;--bslib-color-bg: #56529b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #56529b;color:#fff}.bg-gradient-indigo-teal{--bslib-color-fg: #fff;--bslib-color-bg: #4a5ace;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #4a5ace;color:#fff}.bg-gradient-indigo-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #7a2bdc;background:linear-gradient(var(--bg-gradient-deg, 140deg), #6610f2 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #7a2bdc;color:#fff}.bg-gradient-purple-blue{--bslib-color-fg: #fff;--bslib-color-bg: #4a58a5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #4a58a5;color:#fff}.bg-gradient-purple-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #632bab;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #632bab;color:#fff}.bg-gradient-purple-pink{--bslib-color-fg: #fff;--bslib-color-bg: #973d82;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #973d82;color:#fff}.bg-gradient-purple-red{--bslib-color-fg: #fff;--bslib-color-bg: #a02561;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #a02561;color:#fff}.bg-gradient-purple-orange{--bslib-color-fg: #fff;--bslib-color-bg: #9a6a6a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #9a6a6a;color:#fff}.bg-gradient-purple-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #a05354;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #a05354;color:#fff}.bg-gradient-purple-green{--bslib-color-fg: #fff;--bslib-color-bg: #536d54;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #536d54;color:#fff}.bg-gradient-purple-teal{--bslib-color-fg: #fff;--bslib-color-bg: #477587;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #477587;color:#fff}.bg-gradient-purple-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #774695;background:linear-gradient(var(--bg-gradient-deg, 140deg), #613d7c var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #774695;color:#fff}.bg-gradient-pink-blue{--bslib-color-fg: #fff;--bslib-color-bg: #9b58af;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #9b58af;color:#fff}.bg-gradient-pink-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #b42cb5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #b42cb5;color:#fff}.bg-gradient-pink-purple{--bslib-color-fg: #fff;--bslib-color-bg: #b23e86;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #b23e86;color:#fff}.bg-gradient-pink-red{--bslib-color-fg: #fff;--bslib-color-bg: #f1256b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #f1256b;color:#fff}.bg-gradient-pink-orange{--bslib-color-fg: #fff;--bslib-color-bg: #eb6a73;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #eb6a73;color:#fff}.bg-gradient-pink-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #f1545e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #f1545e;color:#fff}.bg-gradient-pink-green{--bslib-color-fg: #fff;--bslib-color-bg: #a46e5e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #a46e5e;color:#fff}.bg-gradient-pink-teal{--bslib-color-fg: #fff;--bslib-color-bg: #987690;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #987690;color:#fff}.bg-gradient-pink-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #c8479f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #e83e8c var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #c8479f;color:#fff}.bg-gradient-red-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a9337d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a9337d;color:#fff}.bg-gradient-red-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #c20683;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c20683;color:#fff}.bg-gradient-red-purple{--bslib-color-fg: #fff;--bslib-color-bg: #c01854;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #c01854;color:#fff}.bg-gradient-red-pink{--bslib-color-fg: #fff;--bslib-color-bg: #f6195a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #f6195a;color:#fff}.bg-gradient-red-orange{--bslib-color-fg: #fff;--bslib-color-bg: #f94541;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #f94541;color:#fff}.bg-gradient-red-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #ff2f2c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #ff2f2c;color:#fff}.bg-gradient-red-green{--bslib-color-fg: #fff;--bslib-color-bg: #b2492c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #b2492c;color:#fff}.bg-gradient-red-teal{--bslib-color-fg: #fff;--bslib-color-bg: #a6505f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6505f;color:#fff}.bg-gradient-red-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #d6226d;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff0039 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #d6226d;color:#fff}.bg-gradient-orange-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a09b8a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a09b8a;color:#fff}.bg-gradient-orange-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #b96e90;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #b96e90;color:#fff}.bg-gradient-orange-purple{--bslib-color-fg: #fff;--bslib-color-bg: #b78060;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #b78060;color:#fff}.bg-gradient-orange-pink{--bslib-color-fg: #fff;--bslib-color-bg: #ed8167;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #ed8167;color:#fff}.bg-gradient-orange-red{--bslib-color-fg: #fff;--bslib-color-bg: #f66846;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #f66846;color:#fff}.bg-gradient-orange-yellow{--bslib-color-fg: #000;--bslib-color-bg: #f69738;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #f69738;color:#000}.bg-gradient-orange-green{--bslib-color-fg: #000;--bslib-color-bg: #a9b138;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #a9b138;color:#000}.bg-gradient-orange-teal{--bslib-color-fg: #000;--bslib-color-bg: #9db86b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #9db86b;color:#000}.bg-gradient-orange-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #cd897a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #f0ad4e var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #cd897a;color:#fff}.bg-gradient-yellow-blue{--bslib-color-fg: #fff;--bslib-color-bg: #a97969;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #a97969;color:#fff}.bg-gradient-yellow-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #c24d6f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #c24d6f;color:#fff}.bg-gradient-yellow-purple{--bslib-color-fg: #fff;--bslib-color-bg: #c05f40;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #c05f40;color:#fff}.bg-gradient-yellow-pink{--bslib-color-fg: #fff;--bslib-color-bg: #f65f46;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #f65f46;color:#fff}.bg-gradient-yellow-red{--bslib-color-fg: #fff;--bslib-color-bg: #ff4625;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #ff4625;color:#fff}.bg-gradient-yellow-orange{--bslib-color-fg: #000;--bslib-color-bg: #f98b2e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #f98b2e;color:#000}.bg-gradient-yellow-green{--bslib-color-fg: #fff;--bslib-color-bg: #b28f18;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #b28f18;color:#fff}.bg-gradient-yellow-teal{--bslib-color-fg: #fff;--bslib-color-bg: #a6974b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #a6974b;color:#fff}.bg-gradient-yellow-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #d66859;background:linear-gradient(var(--bg-gradient-deg, 140deg), #ff7518 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #d66859;color:#fff}.bg-gradient-green-blue{--bslib-color-fg: #fff;--bslib-color-bg: #35a069;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #35a069;color:#fff}.bg-gradient-green-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #4f746f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #4f746f;color:#fff}.bg-gradient-green-purple{--bslib-color-fg: #fff;--bslib-color-bg: #4d8640;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #4d8640;color:#fff}.bg-gradient-green-pink{--bslib-color-fg: #fff;--bslib-color-bg: #838646;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #838646;color:#fff}.bg-gradient-green-red{--bslib-color-fg: #fff;--bslib-color-bg: #8c6d25;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #8c6d25;color:#fff}.bg-gradient-green-orange{--bslib-color-fg: #000;--bslib-color-bg: #86b22e;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #86b22e;color:#000}.bg-gradient-green-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #8c9c18;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #8c9c18;color:#fff}.bg-gradient-green-teal{--bslib-color-fg: #000;--bslib-color-bg: #33be4b;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #33be4b;color:#000}.bg-gradient-green-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #638f59;background:linear-gradient(var(--bg-gradient-deg, 140deg), #3fb618 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #638f59;color:#fff}.bg-gradient-teal-blue{--bslib-color-fg: #fff;--bslib-color-bg: #23acb5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #23acb5;color:#fff}.bg-gradient-teal-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #3c7fbb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #3c7fbb;color:#fff}.bg-gradient-teal-purple{--bslib-color-fg: #fff;--bslib-color-bg: #3a918c;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #3a918c;color:#fff}.bg-gradient-teal-pink{--bslib-color-fg: #fff;--bslib-color-bg: #709193;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #709193;color:#fff}.bg-gradient-teal-red{--bslib-color-fg: #fff;--bslib-color-bg: #797971;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #797971;color:#fff}.bg-gradient-teal-orange{--bslib-color-fg: #000;--bslib-color-bg: #73be7a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #73be7a;color:#000}.bg-gradient-teal-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #79a764;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #79a764;color:#fff}.bg-gradient-teal-green{--bslib-color-fg: #000;--bslib-color-bg: #2cc164;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #2cc164;color:#000}.bg-gradient-teal-cyan{--bslib-color-fg: #fff;--bslib-color-bg: #509aa5;background:linear-gradient(var(--bg-gradient-deg, 140deg), #20c997 var(--bg-gradient-start, 36%), #9954bb var(--bg-gradient-end, 180%)) #509aa5;color:#fff}.bg-gradient-cyan-blue{--bslib-color-fg: #fff;--bslib-color-bg: #6b66cb;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #2780e3 var(--bg-gradient-end, 180%)) #6b66cb;color:#fff}.bg-gradient-cyan-indigo{--bslib-color-fg: #fff;--bslib-color-bg: #8539d1;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #6610f2 var(--bg-gradient-end, 180%)) #8539d1;color:#fff}.bg-gradient-cyan-purple{--bslib-color-fg: #fff;--bslib-color-bg: #834ba2;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #613d7c var(--bg-gradient-end, 180%)) #834ba2;color:#fff}.bg-gradient-cyan-pink{--bslib-color-fg: #fff;--bslib-color-bg: #b94ba8;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #e83e8c var(--bg-gradient-end, 180%)) #b94ba8;color:#fff}.bg-gradient-cyan-red{--bslib-color-fg: #fff;--bslib-color-bg: #c23287;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #ff0039 var(--bg-gradient-end, 180%)) #c23287;color:#fff}.bg-gradient-cyan-orange{--bslib-color-fg: #fff;--bslib-color-bg: #bc788f;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #f0ad4e var(--bg-gradient-end, 180%)) #bc788f;color:#fff}.bg-gradient-cyan-yellow{--bslib-color-fg: #fff;--bslib-color-bg: #c2617a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #ff7518 var(--bg-gradient-end, 180%)) #c2617a;color:#fff}.bg-gradient-cyan-green{--bslib-color-fg: #fff;--bslib-color-bg: #757b7a;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #3fb618 var(--bg-gradient-end, 180%)) #757b7a;color:#fff}.bg-gradient-cyan-teal{--bslib-color-fg: #fff;--bslib-color-bg: #6983ad;background:linear-gradient(var(--bg-gradient-deg, 140deg), #9954bb var(--bg-gradient-start, 36%), #20c997 var(--bg-gradient-end, 180%)) #6983ad;color:#fff}@media(min-width: 576px){.nav:not(.nav-hidden){display:flex !important;display:-webkit-flex !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column){float:none !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.bslib-nav-spacer{margin-left:auto !important}.nav:not(.nav-hidden):not(.nav-stacked):not(.flex-column)>.form-inline{margin-top:auto;margin-bottom:auto}.nav:not(.nav-hidden).nav-stacked{flex-direction:column;-webkit-flex-direction:column;height:100%}.nav:not(.nav-hidden).nav-stacked>.bslib-nav-spacer{margin-top:auto !important}}.bslib-grid{display:grid !important;gap:var(--bslib-spacer, 1rem);height:var(--bslib-grid-height)}.bslib-grid.grid{grid-template-columns:repeat(var(--bs-columns, 12), minmax(0, 1fr));grid-template-rows:unset;grid-auto-rows:var(--bslib-grid--row-heights);--bslib-grid--row-heights--xs: unset;--bslib-grid--row-heights--sm: unset;--bslib-grid--row-heights--md: unset;--bslib-grid--row-heights--lg: unset;--bslib-grid--row-heights--xl: unset;--bslib-grid--row-heights--xxl: unset}.bslib-grid.grid.bslib-grid--row-heights--xs{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xs)}@media(min-width: 576px){.bslib-grid.grid.bslib-grid--row-heights--sm{--bslib-grid--row-heights: var(--bslib-grid--row-heights--sm)}}@media(min-width: 768px){.bslib-grid.grid.bslib-grid--row-heights--md{--bslib-grid--row-heights: var(--bslib-grid--row-heights--md)}}@media(min-width: 992px){.bslib-grid.grid.bslib-grid--row-heights--lg{--bslib-grid--row-heights: var(--bslib-grid--row-heights--lg)}}@media(min-width: 1200px){.bslib-grid.grid.bslib-grid--row-heights--xl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xl)}}@media(min-width: 1400px){.bslib-grid.grid.bslib-grid--row-heights--xxl{--bslib-grid--row-heights: var(--bslib-grid--row-heights--xxl)}}.bslib-grid>*>.shiny-input-container{width:100%}.bslib-grid-item{grid-column:auto/span 1}@media(max-width: 767.98px){.bslib-grid-item{grid-column:1/-1}}@media(max-width: 575.98px){.bslib-grid{grid-template-columns:1fr !important;height:var(--bslib-grid-height-mobile)}.bslib-grid.grid{height:unset !important;grid-auto-rows:var(--bslib-grid--row-heights--xs, auto)}}.bslib-card{overflow:auto}.bslib-card .card-body+.card-body{padding-top:0}.bslib-card .card-body{overflow:auto}.bslib-card .card-body p{margin-top:0}.bslib-card .card-body p:last-child{margin-bottom:0}.bslib-card .card-body{max-height:var(--bslib-card-body-max-height, none)}.bslib-card[data-full-screen=true]>.card-body{max-height:var(--bslib-card-body-max-height-full-screen, none)}.bslib-card .card-header .form-group{margin-bottom:0}.bslib-card .card-header .selectize-control{margin-bottom:0}.bslib-card .card-header .selectize-control .item{margin-right:1.15rem}.bslib-card .card-footer{margin-top:auto}.bslib-card .bslib-navs-card-title{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center}.bslib-card .bslib-navs-card-title .nav{margin-left:auto}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border=true]){border:none}.bslib-card .bslib-sidebar-layout:not([data-bslib-sidebar-border-radius=true]){border-top-left-radius:0;border-top-right-radius:0}[data-full-screen=true]{position:fixed;inset:3.5rem 1rem 1rem;height:auto !important;max-height:none !important;width:auto !important;z-index:1070}.bslib-full-screen-enter{display:none;position:absolute;bottom:var(--bslib-full-screen-enter-bottom, 0.2rem);right:var(--bslib-full-screen-enter-right, 0);top:var(--bslib-full-screen-enter-top);left:var(--bslib-full-screen-enter-left);color:var(--bslib-color-fg, var(--bs-card-color));background-color:var(--bslib-color-bg, var(--bs-card-bg, var(--bs-body-bg)));border:var(--bs-card-border-width) solid var(--bslib-color-fg, var(--bs-card-border-color));box-shadow:0 2px 4px rgba(0,0,0,.15);margin:.2rem .4rem;padding:.55rem !important;font-size:.8rem;cursor:pointer;opacity:.7;z-index:1070}.bslib-full-screen-enter:hover{opacity:1}.card[data-full-screen=false]:hover>*>.bslib-full-screen-enter{display:block}.bslib-has-full-screen .card:hover>*>.bslib-full-screen-enter{display:none}@media(max-width: 575.98px){.bslib-full-screen-enter{display:none !important}}.bslib-full-screen-exit{position:relative;top:1.35rem;font-size:.9rem;cursor:pointer;text-decoration:none;display:flex;float:right;margin-right:2.15rem;align-items:center;color:rgba(var(--bs-body-bg-rgb), 0.8)}.bslib-full-screen-exit:hover{color:rgba(var(--bs-body-bg-rgb), 1)}.bslib-full-screen-exit svg{margin-left:.5rem;font-size:1.5rem}#bslib-full-screen-overlay{position:fixed;inset:0;background-color:rgba(var(--bs-body-color-rgb), 0.6);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);z-index:1069;animation:bslib-full-screen-overlay-enter 400ms cubic-bezier(0.6, 0.02, 0.65, 1) forwards}@keyframes bslib-full-screen-overlay-enter{0%{opacity:0}100%{opacity:1}}html{height:100%}.bslib-page-fill{width:100%;height:100%;margin:0;padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}@media(max-width: 575.98px){.bslib-page-fill{height:var(--bslib-page-fill-mobile-height, auto)}}.bslib-sidebar-layout{--bslib-sidebar-transition-duration: 500ms;--bslib-sidebar-transition-easing-x: cubic-bezier(0.8, 0.78, 0.22, 1.07);--bslib-sidebar-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-border-radius: var(--bs-border-radius);--bslib-sidebar-vert-border: var(--bs-card-border-width, 1px) solid var(--bs-card-border-color, rgba(0, 0, 0, 0.175));--bslib-sidebar-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.05);--bslib-sidebar-fg: var(--bs-emphasis-color, black);--bslib-sidebar-main-fg: var(--bs-card-color, var(--bs-body-color));--bslib-sidebar-main-bg: var(--bs-card-bg, var(--bs-body-bg));--bslib-sidebar-toggle-bg: rgba(var(--bs-emphasis-color-rgb, 0, 0, 0), 0.1);--bslib-sidebar-padding: calc(var(--bslib-spacer) * 1.5);--bslib-sidebar-icon-size: var(--bslib-spacer, 1rem);--bslib-sidebar-icon-button-size: calc(var(--bslib-sidebar-icon-size, 1rem) * 2);--bslib-sidebar-padding-icon: calc(var(--bslib-sidebar-icon-button-size, 2rem) * 1.5);--bslib-collapse-toggle-border-radius: var(--bs-border-radius, 0.25rem);--bslib-collapse-toggle-transform: 0deg;--bslib-sidebar-toggle-transition-easing: cubic-bezier(1, 0, 0, 1);--bslib-collapse-toggle-right-transform: 180deg;--bslib-sidebar-column-main: minmax(0, 1fr);display:grid !important;grid-template-columns:min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px)) var(--bslib-sidebar-column-main);position:relative;transition:grid-template-columns ease-in-out var(--bslib-sidebar-transition-duration);border:var(--bslib-sidebar-border);border-radius:var(--bslib-sidebar-border-radius)}@media(prefers-reduced-motion: reduce){.bslib-sidebar-layout{transition:none}}.bslib-sidebar-layout[data-bslib-sidebar-border=false]{border:none}.bslib-sidebar-layout[data-bslib-sidebar-border-radius=false]{border-radius:initial}.bslib-sidebar-layout>.main,.bslib-sidebar-layout>.sidebar{grid-row:1/2;border-radius:inherit;overflow:auto}.bslib-sidebar-layout>.main{grid-column:2/3;border-top-left-radius:0;border-bottom-left-radius:0;padding:var(--bslib-sidebar-padding);transition:padding var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration);color:var(--bslib-sidebar-main-fg);background-color:var(--bslib-sidebar-main-bg)}.bslib-sidebar-layout>.sidebar{grid-column:1/2;width:100%;height:100%;border-right:var(--bslib-sidebar-vert-border);border-top-right-radius:0;border-bottom-right-radius:0;color:var(--bslib-sidebar-fg);background-color:var(--bslib-sidebar-bg);backdrop-filter:blur(5px)}.bslib-sidebar-layout>.sidebar>.sidebar-content{display:flex;flex-direction:column;gap:var(--bslib-spacer, 1rem);padding:var(--bslib-sidebar-padding);padding-top:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout>.sidebar>.sidebar-content>:last-child:not(.sidebar-title){margin-bottom:0}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion{margin-left:calc(-1*var(--bslib-sidebar-padding));margin-right:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:last-child{margin-bottom:calc(-1*var(--bslib-sidebar-padding))}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child){margin-bottom:1rem}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion .accordion-body{display:flex;flex-direction:column}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:first-child) .accordion-item:first-child{border-top:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content>.accordion:not(:last-child) .accordion-item:last-child{border-bottom:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.bslib-sidebar-layout>.sidebar>.sidebar-content.has-accordion>.sidebar-title{border-bottom:none;padding-bottom:0}.bslib-sidebar-layout>.sidebar .shiny-input-container{width:100%}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar>.sidebar-content{padding-top:var(--bslib-sidebar-padding)}.bslib-sidebar-layout>.collapse-toggle{grid-row:1/2;grid-column:1/2;display:inline-flex;align-items:center;position:absolute;right:calc(var(--bslib-sidebar-icon-size));top:calc(var(--bslib-sidebar-icon-size, 1rem)/2);border:none;border-radius:var(--bslib-collapse-toggle-border-radius);height:var(--bslib-sidebar-icon-button-size, 2rem);width:var(--bslib-sidebar-icon-button-size, 2rem);display:flex;align-items:center;justify-content:center;padding:0;color:var(--bslib-sidebar-fg);background-color:unset;transition:color var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),top var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),right var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration),left var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover{background-color:var(--bslib-sidebar-toggle-bg)}.bslib-sidebar-layout>.collapse-toggle>.collapse-icon{opacity:.8;width:var(--bslib-sidebar-icon-size);height:var(--bslib-sidebar-icon-size);transform:rotateY(var(--bslib-collapse-toggle-transform));transition:transform var(--bslib-sidebar-toggle-transition-easing) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout>.collapse-toggle:hover>.collapse-icon{opacity:1}.bslib-sidebar-layout .sidebar-title{font-size:1.25rem;line-height:1.25;margin-top:0;margin-bottom:1rem;padding-bottom:1rem;border-bottom:var(--bslib-sidebar-border)}.bslib-sidebar-layout.sidebar-right{grid-template-columns:var(--bslib-sidebar-column-main) min(100% - var(--bslib-sidebar-icon-size),var(--bslib-sidebar-width, 250px))}.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/2;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.bslib-sidebar-layout.sidebar-right>.sidebar{grid-column:2/3;border-right:none;border-left:var(--bslib-sidebar-vert-border);border-top-left-radius:0;border-bottom-left-radius:0}.bslib-sidebar-layout.sidebar-right>.collapse-toggle{grid-column:2/3;left:var(--bslib-sidebar-icon-size);right:unset;border:var(--bslib-collapse-toggle-border)}.bslib-sidebar-layout.sidebar-right>.collapse-toggle>.collapse-icon{transform:rotateY(var(--bslib-collapse-toggle-right-transform))}.bslib-sidebar-layout.sidebar-collapsed{--bslib-collapse-toggle-transform: 180deg;--bslib-collapse-toggle-right-transform: 0deg;--bslib-sidebar-vert-border: none;grid-template-columns:0 minmax(0, 1fr)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right{grid-template-columns:minmax(0, 1fr) 0}.bslib-sidebar-layout.sidebar-collapsed:not(.transitioning)>.sidebar>*{display:none}.bslib-sidebar-layout.sidebar-collapsed>.main{border-radius:inherit}.bslib-sidebar-layout.sidebar-collapsed:not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout.sidebar-collapsed>.collapse-toggle{color:var(--bslib-sidebar-main-fg);top:calc(var(--bslib-sidebar-overlap-counter, 0)*(var(--bslib-sidebar-icon-size) + var(--bslib-sidebar-padding)) + var(--bslib-sidebar-icon-size, 1rem)/2);right:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px))}.bslib-sidebar-layout.sidebar-collapsed.sidebar-right>.collapse-toggle{left:calc(-2.5*var(--bslib-sidebar-icon-size) - var(--bs-card-border-width, 1px));right:unset}@media(min-width: 576px){.bslib-sidebar-layout.transitioning>.sidebar>.sidebar-content{display:none}}@media(max-width: 575.98px){.bslib-sidebar-layout[data-bslib-sidebar-open=desktop]{--bslib-sidebar-js-init-collapsed: true}.bslib-sidebar-layout>.sidebar,.bslib-sidebar-layout.sidebar-right>.sidebar{border:none}.bslib-sidebar-layout>.main,.bslib-sidebar-layout.sidebar-right>.main{grid-column:1/3}.bslib-sidebar-layout[data-bslib-sidebar-open=always]{display:block !important}.bslib-sidebar-layout[data-bslib-sidebar-open=always]>.sidebar{max-height:var(--bslib-sidebar-max-height-mobile);overflow-y:auto;border-top:var(--bslib-sidebar-vert-border)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]){grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.sidebar{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-collapsed)>.collapse-toggle{z-index:1}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed{grid-template-columns:0 100%}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed.sidebar-right{grid-template-columns:100% 0}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]):not(.sidebar-right)>.main{padding-left:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-right>.main{padding-right:var(--bslib-sidebar-padding-icon)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always])>.main{opacity:0;transition:opacity var(--bslib-sidebar-transition-easing-x) var(--bslib-sidebar-transition-duration)}.bslib-sidebar-layout:not([data-bslib-sidebar-open=always]).sidebar-collapsed>.main{opacity:1}}:root{--bslib-value-box-shadow: none;--bslib-value-box-border-width-auto-yes: var(--bslib-value-box-border-width-baseline);--bslib-value-box-border-width-auto-no: 0;--bslib-value-box-border-width-baseline: 1px}.bslib-value-box{border-width:var(--bslib-value-box-border-width-auto-no, var(--bslib-value-box-border-width-baseline));container-name:bslib-value-box;container-type:inline-size}.bslib-value-box.card{box-shadow:var(--bslib-value-box-shadow)}.bslib-value-box.border-auto{border-width:var(--bslib-value-box-border-width-auto-yes, var(--bslib-value-box-border-width-baseline))}.bslib-value-box.default{--bslib-value-box-bg-default: var(--bs-card-bg, #fff);--bslib-value-box-border-color-default: var(--bs-card-border-color, rgba(0, 0, 0, 0.175));color:var(--bslib-value-box-color);background-color:var(--bslib-value-box-bg, var(--bslib-value-box-bg-default));border-color:var(--bslib-value-box-border-color, var(--bslib-value-box-border-color-default))}.bslib-value-box .value-box-grid{display:grid;grid-template-areas:"left right";align-items:center;overflow:hidden}.bslib-value-box .value-box-showcase{height:100%;max-height:var(---bslib-value-box-showcase-max-h, 100%)}.bslib-value-box .value-box-showcase,.bslib-value-box .value-box-showcase>.html-fill-item{width:100%}.bslib-value-box[data-full-screen=true] .value-box-showcase{max-height:var(---bslib-value-box-showcase-max-h-fs, 100%)}@media screen and (min-width: 575.98px){@container bslib-value-box (max-width: 300px){.bslib-value-box:not(.showcase-bottom) .value-box-grid{grid-template-columns:1fr !important;grid-template-rows:auto auto;grid-template-areas:"top" "bottom"}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-showcase{grid-area:top !important}.bslib-value-box:not(.showcase-bottom) .value-box-grid .value-box-area{grid-area:bottom !important;justify-content:end}}}.bslib-value-box .value-box-area{justify-content:center;padding:1.5rem 1rem;font-size:.9rem;font-weight:500}.bslib-value-box .value-box-area *{margin-bottom:0;margin-top:0}.bslib-value-box .value-box-title{font-size:1rem;margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}.bslib-value-box .value-box-title:empty::after{content:" "}.bslib-value-box .value-box-value{font-size:calc(1.29rem + 0.48vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}@media(min-width: 1200px){.bslib-value-box .value-box-value{font-size:1.65rem}}.bslib-value-box .value-box-value:empty::after{content:" "}.bslib-value-box .value-box-showcase{align-items:center;justify-content:center;margin-top:auto;margin-bottom:auto;padding:1rem}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{opacity:.85;min-width:50px;max-width:125%}.bslib-value-box .value-box-showcase .bi,.bslib-value-box .value-box-showcase .fa,.bslib-value-box .value-box-showcase .fab,.bslib-value-box .value-box-showcase .fas,.bslib-value-box .value-box-showcase .far{font-size:4rem}.bslib-value-box.showcase-top-right .value-box-grid{grid-template-columns:1fr var(---bslib-value-box-showcase-w, 50%)}.bslib-value-box.showcase-top-right .value-box-grid .value-box-showcase{grid-area:right;margin-left:auto;align-self:start;align-items:end;padding-left:0;padding-bottom:0}.bslib-value-box.showcase-top-right .value-box-grid .value-box-area{grid-area:left;align-self:end}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid{grid-template-columns:auto var(---bslib-value-box-showcase-w-fs, 1fr)}.bslib-value-box.showcase-top-right[data-full-screen=true] .value-box-grid>div{align-self:center}.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-showcase{margin-top:0}@container bslib-value-box (max-width: 300px){.bslib-value-box.showcase-top-right:not([data-full-screen=true]) .value-box-grid .value-box-showcase{padding-left:1rem}}.bslib-value-box.showcase-left-center .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w, 30%) auto}.bslib-value-box.showcase-left-center[data-full-screen=true] .value-box-grid{grid-template-columns:var(---bslib-value-box-showcase-w-fs, 1fr) auto}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-showcase{grid-area:left}.bslib-value-box.showcase-left-center:not([data-fill-screen=true]) .value-box-grid .value-box-area{grid-area:right}.bslib-value-box.showcase-bottom .value-box-grid{grid-template-columns:1fr;grid-template-rows:1fr var(---bslib-value-box-showcase-h, auto);grid-template-areas:"top" "bottom";overflow:hidden}.bslib-value-box.showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.bslib-value-box.showcase-bottom .value-box-grid .value-box-area{grid-area:top}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid{grid-template-rows:1fr var(---bslib-value-box-showcase-h-fs, 2fr)}.bslib-value-box.showcase-bottom[data-full-screen=true] .value-box-grid .value-box-showcase{padding:1rem}[data-bs-theme=dark] .bslib-value-box{--bslib-value-box-shadow: 0 0.5rem 1rem rgb(0 0 0 / 50%)}.navbar+.container-fluid:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-sm:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-md:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-lg:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xl:has(>.tab-content>.tab-pane.active.html-fill-container),.navbar+.container-xxl:has(>.tab-content>.tab-pane.active.html-fill-container){padding-left:0;padding-right:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container,.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container{padding:var(--bslib-spacer, 1rem);gap:var(--bslib-spacer, 1rem)}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container:has(>.bslib-sidebar-layout:only-child){padding:0}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border=true]){border-left:none;border-right:none;border-bottom:none}.navbar+.container-fluid>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-sm>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-md>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-lg>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]),.navbar+.container-xxl>.tab-content>.tab-pane.active.html-fill-container>.bslib-sidebar-layout:only-child:not([data-bslib-sidebar-border-radius=true]){border-radius:0}.navbar+div>.bslib-sidebar-layout{border-top:var(--bslib-sidebar-border)}.accordion .accordion-header{font-size:calc(1.29rem + 0.48vw);margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2;color:var(--bs-heading-color);margin-bottom:0}@media(min-width: 1200px){.accordion .accordion-header{font-size:1.65rem}}.accordion .accordion-icon:not(:empty){margin-right:.75rem;display:flex}.accordion .accordion-button:not(.collapsed){box-shadow:none}.accordion .accordion-button:not(.collapsed):focus{box-shadow:var(--bs-accordion-btn-focus-box-shadow)}:root{--bslib-page-sidebar-title-bg: #2780e3;--bslib-page-sidebar-title-color: #fff}.bslib-page-title{background-color:var(--bslib-page-sidebar-title-bg);color:var(--bslib-page-sidebar-title-color);font-size:1.25rem;font-weight:300;padding:var(--bslib-spacer, 1rem);padding-left:1.5rem;margin-bottom:0;border-bottom:1px solid #dee2e6}.html-fill-container{display:flex;flex-direction:column;min-height:0;min-width:0}.html-fill-container>.html-fill-item{flex:1 1 auto;min-height:0;min-width:0}.html-fill-container>:not(.html-fill-item){flex:0 0 auto}.quarto-container{min-height:calc(100vh - 132px)}body.hypothesis-enabled #quarto-header{margin-right:16px}footer.footer .nav-footer,#quarto-header>nav{padding-left:1em;padding-right:1em}footer.footer div.nav-footer p:first-child{margin-top:0}footer.footer div.nav-footer p:last-child{margin-bottom:0}#quarto-content>*{padding-top:14px}#quarto-content>#quarto-sidebar-glass{padding-top:0px}@media(max-width: 991.98px){#quarto-content>*{padding-top:0}#quarto-content .subtitle{padding-top:14px}#quarto-content section:first-of-type h2:first-of-type,#quarto-content section:first-of-type .h2:first-of-type{margin-top:1rem}}.headroom-target,header.headroom{will-change:transform;transition:position 200ms linear;transition:all 200ms linear}header.headroom--pinned{transform:translateY(0%)}header.headroom--unpinned{transform:translateY(-100%)}.navbar-container{width:100%}.navbar-brand{overflow:hidden;text-overflow:ellipsis}.navbar-brand-container{max-width:calc(100% - 115px);min-width:0;display:flex;align-items:center}@media(min-width: 992px){.navbar-brand-container{margin-right:1em}}.navbar-brand.navbar-brand-logo{margin-right:4px;display:inline-flex}.navbar-toggler{flex-basis:content;flex-shrink:0}.navbar .navbar-brand-container{order:2}.navbar .navbar-toggler{order:1}.navbar .navbar-container>.navbar-nav{order:20}.navbar .navbar-container>.navbar-brand-container{margin-left:0 !important;margin-right:0 !important}.navbar .navbar-collapse{order:20}.navbar #quarto-search{order:4;margin-left:auto}.navbar .navbar-toggler{margin-right:.5em}.navbar-collapse .quarto-navbar-tools{margin-left:.5em}.navbar-logo{max-height:24px;width:auto;padding-right:4px}nav .nav-item:not(.compact){padding-top:1px}nav .nav-link i,nav .dropdown-item i{padding-right:1px}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.6rem;padding-right:.6rem}nav .nav-item.compact .nav-link{padding-left:.5rem;padding-right:.5rem;font-size:1.1rem}.navbar .quarto-navbar-tools{order:3}.navbar .quarto-navbar-tools div.dropdown{display:inline-block}.navbar .quarto-navbar-tools .quarto-navigation-tool{color:#fdfeff}.navbar .quarto-navbar-tools .quarto-navigation-tool:hover{color:#fdfdff}.navbar-nav .dropdown-menu{min-width:220px;font-size:.9rem}.navbar .navbar-nav .nav-link.dropdown-toggle::after{opacity:.75;vertical-align:.175em}.navbar ul.dropdown-menu{padding-top:0;padding-bottom:0}.navbar .dropdown-header{text-transform:uppercase;font-size:.8rem;padding:0 .5rem}.navbar .dropdown-item{padding:.4rem .5rem}.navbar .dropdown-item>i.bi{margin-left:.1rem;margin-right:.25em}.sidebar #quarto-search{margin-top:-1px}.sidebar #quarto-search svg.aa-SubmitIcon{width:16px;height:16px}.sidebar-navigation a{color:inherit}.sidebar-title{margin-top:.25rem;padding-bottom:.5rem;font-size:1.3rem;line-height:1.6rem;visibility:visible}.sidebar-title>a{font-size:inherit;text-decoration:none}.sidebar-title .sidebar-tools-main{margin-top:-6px}@media(max-width: 991.98px){#quarto-sidebar div.sidebar-header{padding-top:.2em}}.sidebar-header-stacked .sidebar-title{margin-top:.6rem}.sidebar-logo{max-width:90%;padding-bottom:.5rem}.sidebar-logo-link{text-decoration:none}.sidebar-navigation li a{text-decoration:none}.sidebar-navigation .quarto-navigation-tool{opacity:.7;font-size:.875rem}#quarto-sidebar>nav>.sidebar-tools-main{margin-left:14px}.sidebar-tools-main{display:inline-flex;margin-left:0px;order:2}.sidebar-tools-main:not(.tools-wide){vertical-align:middle}.sidebar-navigation .quarto-navigation-tool.dropdown-toggle::after{display:none}.sidebar.sidebar-navigation>*{padding-top:1em}.sidebar-item{margin-bottom:.2em;line-height:1rem;margin-top:.4rem}.sidebar-section{padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between;cursor:pointer}.sidebar-item-toggle:hover{cursor:pointer}.sidebar-item .sidebar-item-toggle .bi{font-size:.7rem;text-align:center}.sidebar-item .sidebar-item-toggle .bi-chevron-right::before{transition:transform 200ms ease}.sidebar-item .sidebar-item-toggle[aria-expanded=false] .bi-chevron-right::before{transform:none}.sidebar-item .sidebar-item-toggle[aria-expanded=true] .bi-chevron-right::before{transform:rotate(90deg)}.sidebar-item-text{width:100%}.sidebar-navigation .sidebar-divider{margin-left:0;margin-right:0;margin-top:.5rem;margin-bottom:.5rem}@media(max-width: 991.98px){.quarto-secondary-nav{display:block}.quarto-secondary-nav button.quarto-search-button{padding-right:0em;padding-left:2em}.quarto-secondary-nav button.quarto-btn-toggle{margin-left:-0.75rem;margin-right:.15rem}.quarto-secondary-nav nav.quarto-title-breadcrumbs{display:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs{display:flex;align-items:center;padding-right:1em;margin-left:-0.25em}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{text-decoration:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs ol.breadcrumb{margin-bottom:0}}@media(min-width: 992px){.quarto-secondary-nav{display:none}}.quarto-title-breadcrumbs .breadcrumb{margin-bottom:.5em;font-size:.9rem}.quarto-title-breadcrumbs .breadcrumb li:last-of-type a{color:#6c757d}.quarto-secondary-nav .quarto-btn-toggle{color:#595959}.quarto-secondary-nav[aria-expanded=false] .quarto-btn-toggle .bi-chevron-right::before{transform:none}.quarto-secondary-nav[aria-expanded=true] .quarto-btn-toggle .bi-chevron-right::before{transform:rotate(90deg)}.quarto-secondary-nav .quarto-btn-toggle .bi-chevron-right::before{transition:transform 200ms ease}.quarto-secondary-nav{cursor:pointer}.no-decor{text-decoration:none}.quarto-secondary-nav-title{margin-top:.3em;color:#595959;padding-top:4px}.quarto-secondary-nav nav.quarto-page-breadcrumbs{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a:hover{color:rgba(33,81,191,.8)}.quarto-secondary-nav nav.quarto-page-breadcrumbs .breadcrumb-item::before{color:#8c8c8c}.breadcrumb-item{line-height:1.2rem}div.sidebar-item-container{color:#595959}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(33,81,191,.8)}div.sidebar-item-container.disabled{color:rgba(89,89,89,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:#2151bf}div.sidebar.sidebar-navigation.rollup.quarto-sidebar-toggle-contents,nav.sidebar.sidebar-navigation:not(.rollup){background-color:#fff}@media(max-width: 991.98px){.sidebar-navigation .sidebar-item a,.nav-page .nav-page-text,.sidebar-navigation{font-size:1rem}.sidebar-navigation ul.sidebar-section.depth1 .sidebar-section-item{font-size:1.1rem}.sidebar-logo{display:none}.sidebar.sidebar-navigation{position:static;border-bottom:1px solid #dee2e6}.sidebar.sidebar-navigation.collapsing{position:fixed;z-index:1000}.sidebar.sidebar-navigation.show{position:fixed;z-index:1000}.sidebar.sidebar-navigation{min-height:100%}nav.quarto-secondary-nav{background-color:#fff;border-bottom:1px solid #dee2e6}.quarto-banner nav.quarto-secondary-nav{background-color:#2780e3;color:#fdfeff;border-top:1px solid #dee2e6}.sidebar .sidebar-footer{visibility:visible;padding-top:1rem;position:inherit}.sidebar-tools-collapse{display:block}}#quarto-sidebar{transition:width .15s ease-in}#quarto-sidebar>*{padding-right:1em}@media(max-width: 991.98px){#quarto-sidebar .sidebar-menu-container{white-space:nowrap;min-width:225px}#quarto-sidebar.show{transition:width .15s ease-out}}@media(min-width: 992px){#quarto-sidebar{display:flex;flex-direction:column}.nav-page .nav-page-text,.sidebar-navigation .sidebar-section .sidebar-item{font-size:.875rem}.sidebar-navigation .sidebar-item{font-size:.925rem}.sidebar.sidebar-navigation{display:block;position:sticky}.sidebar-search{width:100%}.sidebar .sidebar-footer{visibility:visible}}@media(min-width: 992px){#quarto-sidebar-glass{display:none}}@media(max-width: 991.98px){#quarto-sidebar-glass{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,0);transition:background-color .15s ease-in;z-index:-1}#quarto-sidebar-glass.collapsing{z-index:1000}#quarto-sidebar-glass.show{transition:background-color .15s ease-out;background-color:rgba(102,102,102,.4);z-index:1000}}.sidebar .sidebar-footer{padding:.5rem 1rem;align-self:flex-end;color:#6c757d;width:100%}.quarto-page-breadcrumbs .breadcrumb-item+.breadcrumb-item,.quarto-page-breadcrumbs .breadcrumb-item{padding-right:.33em;padding-left:0}.quarto-page-breadcrumbs .breadcrumb-item::before{padding-right:.33em}.quarto-sidebar-footer{font-size:.875em}.sidebar-section .bi-chevron-right{vertical-align:middle}.sidebar-section .bi-chevron-right::before{font-size:.9em}.notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;transition:none !important}.btn:focus:not(:focus-visible){box-shadow:none}.page-navigation{display:flex;justify-content:space-between}.nav-page{padding-bottom:.75em}.nav-page .bi{font-size:1.8rem;vertical-align:middle}.nav-page .nav-page-text{padding-left:.25em;padding-right:.25em}.nav-page a{color:#6c757d;text-decoration:none;display:flex;align-items:center}.nav-page a:hover{color:#1f4eb6}.nav-footer .toc-actions{padding-bottom:.5em;padding-top:.5em}.nav-footer .toc-actions a,.nav-footer .toc-actions a:hover{text-decoration:none}.nav-footer .toc-actions ul{display:flex;list-style:none}.nav-footer .toc-actions ul :first-child{margin-left:auto}.nav-footer .toc-actions ul :last-child{margin-right:auto}.nav-footer .toc-actions ul li{padding-right:1.5em}.nav-footer .toc-actions ul li i.bi{padding-right:.4em}.nav-footer .toc-actions ul li:last-of-type{padding-right:0}.nav-footer{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;text-align:center;padding-top:.5rem;padding-bottom:.5rem;background-color:#fff}body.nav-fixed{padding-top:64px}.nav-footer-contents{color:#6c757d;margin-top:.25rem}.nav-footer{min-height:3.5em;color:#757575}.nav-footer a{color:#757575}.nav-footer .nav-footer-left{font-size:.825em}.nav-footer .nav-footer-center{font-size:.825em}.nav-footer .nav-footer-right{font-size:.825em}.nav-footer-left .footer-items,.nav-footer-center .footer-items,.nav-footer-right .footer-items{display:inline-flex;padding-top:.3em;padding-bottom:.3em;margin-bottom:0em}.nav-footer-left .footer-items .nav-link,.nav-footer-center .footer-items .nav-link,.nav-footer-right .footer-items .nav-link{padding-left:.6em;padding-right:.6em}@media(min-width: 768px){.nav-footer-left{flex:1 1 0px;text-align:left}}@media(max-width: 575.98px){.nav-footer-left{margin-bottom:1em;flex:100%}}@media(min-width: 768px){.nav-footer-right{flex:1 1 0px;text-align:right}}@media(max-width: 575.98px){.nav-footer-right{margin-bottom:1em;flex:100%}}.nav-footer-center{text-align:center;min-height:3em}@media(min-width: 768px){.nav-footer-center{flex:1 1 0px}}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-bottom:1em;flex:100%}}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em;order:10}}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:#fdfeff;border-radius:3px}@media(max-width: 991.98px){.quarto-reader-toggle{display:none}}.quarto-reader-toggle.reader.quarto-navigation-tool .quarto-reader-toggle-btn{background-color:#595959;border-radius:3px}.quarto-reader-toggle .quarto-reader-toggle-btn{display:inline-flex;padding-left:.2em;padding-right:.2em;margin-left:-0.2em;margin-right:-0.2em;text-align:center}.navbar .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}#quarto-back-to-top{display:none;position:fixed;bottom:50px;background-color:#fff;border-radius:.25rem;box-shadow:0 .2rem .5rem #6c757d,0 0 .05rem #6c757d;color:#6c757d;text-decoration:none;font-size:.9em;text-align:center;left:50%;padding:.4rem .8rem;transform:translate(-50%, 0)}#quarto-announcement{padding:.5em;display:flex;justify-content:space-between;margin-bottom:0;font-size:.9em}#quarto-announcement .quarto-announcement-content{margin-right:auto}#quarto-announcement .quarto-announcement-content p{margin-bottom:0}#quarto-announcement .quarto-announcement-icon{margin-right:.5em;font-size:1.2em;margin-top:-0.15em}#quarto-announcement .quarto-announcement-action{cursor:pointer}.aa-DetachedSearchButtonQuery{display:none}.aa-DetachedOverlay ul.aa-List,#quarto-search-results ul.aa-List{list-style:none;padding-left:0}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{background-color:#fff;position:absolute;z-index:2000}#quarto-search-results .aa-Panel{max-width:400px}#quarto-search input{font-size:.925rem}@media(min-width: 992px){.navbar #quarto-search{margin-left:.25rem;order:999}}.navbar.navbar-expand-sm #quarto-search,.navbar.navbar-expand-md #quarto-search{order:999}@media(min-width: 992px){.navbar .quarto-navbar-tools{order:900}}@media(min-width: 992px){.navbar .quarto-navbar-tools.tools-end{margin-left:auto !important}}@media(max-width: 991.98px){#quarto-sidebar .sidebar-search{display:none}}#quarto-sidebar .sidebar-search .aa-Autocomplete{width:100%}.navbar .aa-Autocomplete .aa-Form{width:180px}.navbar #quarto-search.type-overlay .aa-Autocomplete{width:40px}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form{background-color:inherit;border:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form:focus-within{box-shadow:none;outline:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper{display:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper:focus-within{display:inherit}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg{width:26px;height:26px;color:#fdfeff;opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:#fdfeff;opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;color:#343a40;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-Autocomplete .aa-Form:focus-within,.aa-DetachedFormContainer .aa-Form:focus-within{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;order:1}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{cursor:initial;flex-shrink:0;padding:0;text-align:left}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg{color:#343a40;opacity:.5}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton{appearance:none;background:none;border:0;margin:0}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapper,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper{order:3;position:relative;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input{appearance:none;background:none;border:0;color:#343a40;font:inherit;height:calc(1.5em + .1rem + 2px);padding:0;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::placeholder,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::placeholder{color:#343a40;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input:focus{border-color:none;box-shadow:none;outline:none}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix{align-items:center;display:flex;order:4}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton{align-items:center;background:none;border:0;color:#343a40;opacity:.8;cursor:pointer;display:flex;margin:0;width:calc(1.5em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus{color:#343a40;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg{width:calc(1.5em + 0.75rem + calc(1px * 2))}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton{border:none;align-items:center;background:none;color:#343a40;opacity:.4;font-size:.7rem;cursor:pointer;display:none;margin:0;width:calc(1em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus{color:#343a40;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden]{display:none}.aa-PanelLayout:empty{display:none}.quarto-search-no-results.no-query{display:none}.aa-Source:has(.no-query){display:none}#quarto-search-results .aa-Panel{border:solid #dee2e6 1px}#quarto-search-results .aa-SourceNoResults{width:398px}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{max-height:65vh;overflow-y:auto;font-size:.925rem}.aa-DetachedOverlay .aa-SourceNoResults,#quarto-search-results .aa-SourceNoResults{height:60px;display:flex;justify-content:center;align-items:center}.aa-DetachedOverlay .search-error,#quarto-search-results .search-error{padding-top:10px;padding-left:20px;padding-right:20px;cursor:default}.aa-DetachedOverlay .search-error .search-error-title,#quarto-search-results .search-error .search-error-title{font-size:1.1rem;margin-bottom:.5rem}.aa-DetachedOverlay .search-error .search-error-title .search-error-icon,#quarto-search-results .search-error .search-error-title .search-error-icon{margin-right:8px}.aa-DetachedOverlay .search-error .search-error-text,#quarto-search-results .search-error .search-error-text{font-weight:300}.aa-DetachedOverlay .search-result-text,#quarto-search-results .search-result-text{font-weight:300;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2rem;max-height:2.4rem}.aa-DetachedOverlay .aa-SourceHeader .search-result-header,#quarto-search-results .aa-SourceHeader .search-result-header{font-size:.875rem;background-color:#f2f2f2;padding-left:14px;padding-bottom:4px;padding-top:4px}.aa-DetachedOverlay .aa-SourceHeader .search-result-header-no-results,#quarto-search-results .aa-SourceHeader .search-result-header-no-results{display:none}.aa-DetachedOverlay .aa-SourceFooter .algolia-search-logo,#quarto-search-results .aa-SourceFooter .algolia-search-logo{width:110px;opacity:.85;margin:8px;float:right}.aa-DetachedOverlay .search-result-section,#quarto-search-results .search-result-section{font-size:.925em}.aa-DetachedOverlay a.search-result-link,#quarto-search-results a.search-result-link{color:inherit;text-decoration:none}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item,#quarto-search-results li.aa-Item[aria-selected=true] .search-item{background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text-container{color:#fff;background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=true] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-match.mark{color:#fff;background-color:#4b95e8}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item,#quarto-search-results li.aa-Item[aria-selected=false] .search-item{background-color:#fff}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text-container{color:#343a40}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=false] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-match.mark{color:inherit;background-color:#e5effc}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container{background-color:#fff;color:#343a40}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container{padding-top:0px}.aa-DetachedOverlay li.aa-Item .search-result-doc.document-selectable .search-result-text-container,#quarto-search-results li.aa-Item .search-result-doc.document-selectable .search-result-text-container{margin-top:-4px}.aa-DetachedOverlay .aa-Item,#quarto-search-results .aa-Item{cursor:pointer}.aa-DetachedOverlay .aa-Item .search-item,#quarto-search-results .aa-Item .search-item{border-left:none;border-right:none;border-top:none;background-color:#fff;border-color:#dee2e6;color:#343a40}.aa-DetachedOverlay .aa-Item .search-item p,#quarto-search-results .aa-Item .search-item p{margin-top:0;margin-bottom:0}.aa-DetachedOverlay .aa-Item .search-item i.bi,#quarto-search-results .aa-Item .search-item i.bi{padding-left:8px;padding-right:8px;font-size:1.3em}.aa-DetachedOverlay .aa-Item .search-item .search-result-title,#quarto-search-results .aa-Item .search-item .search-result-title{margin-top:.3em;margin-bottom:0em}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs,#quarto-search-results .aa-Item .search-item .search-result-crumbs{white-space:nowrap;text-overflow:ellipsis;font-size:.8em;font-weight:300;margin-right:1em}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs:not(.search-result-crumbs-wrap),#quarto-search-results .aa-Item .search-item .search-result-crumbs:not(.search-result-crumbs-wrap){max-width:30%;margin-left:auto;margin-top:.5em;margin-bottom:.1rem}.aa-DetachedOverlay .aa-Item .search-item .search-result-crumbs.search-result-crumbs-wrap,#quarto-search-results .aa-Item .search-item .search-result-crumbs.search-result-crumbs-wrap{flex-basis:100%;margin-top:0em;margin-bottom:.2em;margin-left:37px}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;flex-wrap:wrap;padding:6px 4px 6px 4px}.aa-DetachedOverlay .aa-Item .search-result-text-container,#quarto-search-results .aa-Item .search-result-text-container{padding-bottom:8px;padding-right:8px;margin-left:42px}.aa-DetachedOverlay .aa-Item .search-result-doc-section,.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-doc-section,#quarto-search-results .aa-Item .search-result-more{padding-top:8px;padding-bottom:8px;padding-left:44px}.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-more{font-size:.8em;font-weight:400}.aa-DetachedOverlay .aa-Item .search-result-doc,#quarto-search-results .aa-Item .search-result-doc{border-top:1px solid #dee2e6}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#fdfeff}.sidebar-tools-collapse #quarto-search,.sidebar-tools-main #quarto-search{display:inline}.sidebar-tools-collapse #quarto-search .aa-Autocomplete,.sidebar-tools-main #quarto-search .aa-Autocomplete{display:inline}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton{padding-left:4px;padding-right:4px}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#595959}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon{margin-top:-3px}.aa-DetachedContainer{background:rgba(255,255,255,.65);width:90%;bottom:0;box-shadow:rgba(222,226,230,.6) 0 0 0 1px;outline:currentColor none medium;display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:1101}.aa-DetachedContainer::after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{background-color:#fff;border-bottom:1px solid #dee2e6;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:.5em}.aa-DetachedCancelButton{background:none;font-size:.8em;border:0;border-radius:3px;color:#343a40;cursor:pointer;margin:0 0 0 .5em;padding:0 .5em}.aa-DetachedCancelButton:hover,.aa-DetachedCancelButton:focus{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-DetachedContainer--modal{bottom:inherit;height:auto;margin:0 auto;position:absolute;top:100px;border-radius:6px;max-width:850px}@media(max-width: 575.98px){.aa-DetachedContainer--modal{width:100%;top:0px;border-radius:0px;border:none}}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:var(--aa-detached-modal-max-height);padding-bottom:var(--aa-spacing-half);position:static}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:rgba(52,58,64,.4);position:fixed;left:0;right:0;top:0;margin:0;padding:0;height:100vh;z-index:1100}.quarto-dashboard.nav-fixed.dashboard-sidebar #quarto-content.quarto-dashboard-content{padding:0em}.quarto-dashboard #quarto-content.quarto-dashboard-content{padding:1em}.quarto-dashboard #quarto-content.quarto-dashboard-content>*{padding-top:0}@media(min-width: 576px){.quarto-dashboard{height:100%}}.quarto-dashboard .card.valuebox.bslib-card.bg-primary{background-color:#5397e9 !important}.quarto-dashboard .card.valuebox.bslib-card.bg-secondary{background-color:#343a40 !important}.quarto-dashboard .card.valuebox.bslib-card.bg-success{background-color:#3aa716 !important}.quarto-dashboard .card.valuebox.bslib-card.bg-info{background-color:rgba(153,84,187,.7019607843) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-warning{background-color:#fa6400 !important}.quarto-dashboard .card.valuebox.bslib-card.bg-danger{background-color:rgba(255,0,57,.7019607843) !important}.quarto-dashboard .card.valuebox.bslib-card.bg-light{background-color:#f8f9fa !important}.quarto-dashboard .card.valuebox.bslib-card.bg-dark{background-color:#343a40 !important}.quarto-dashboard.dashboard-fill{display:flex;flex-direction:column}.quarto-dashboard #quarto-appendix{display:none}.quarto-dashboard #quarto-header #quarto-dashboard-header{border-top:solid 1px #549be9;border-bottom:solid 1px #549be9}.quarto-dashboard #quarto-header #quarto-dashboard-header>nav{padding-left:1em;padding-right:1em}.quarto-dashboard #quarto-header #quarto-dashboard-header>nav .navbar-brand-container{padding-left:0}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-toggler{margin-right:0}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-toggler-icon{height:1em;width:1em;background-image:url('data:image/svg+xml,')}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-brand-container{padding-right:1em}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-title{font-size:1.1em}.quarto-dashboard #quarto-header #quarto-dashboard-header .navbar-nav{font-size:.9em}.quarto-dashboard #quarto-dashboard-header .navbar{padding:0}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-container{padding-left:1em}.quarto-dashboard #quarto-dashboard-header .navbar.slim .navbar-brand-container .nav-link,.quarto-dashboard #quarto-dashboard-header .navbar.slim .navbar-nav .nav-link{padding:.7em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-color-scheme-toggle{order:9}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-toggler{margin-left:.5em;order:10}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-nav .nav-link{padding:.5em;height:100%;display:flex;align-items:center}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-nav .active{background-color:#4b95e8}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-brand-container{padding:.5em .5em .5em 0;display:flex;flex-direction:row;margin-right:2em;align-items:center}@media(max-width: 767.98px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-brand-container{margin-right:auto}}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{align-self:stretch}@media(min-width: 768px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{order:8}}@media(max-width: 767.98px){.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse{order:1000;padding-bottom:.5em}}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-collapse .navbar-nav{align-self:stretch}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title{font-size:1.25em;line-height:1.1em;display:flex;flex-direction:row;flex-wrap:wrap;align-items:baseline}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title .navbar-title-text{margin-right:.4em}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-title a{text-decoration:none;color:inherit}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-subtitle,.quarto-dashboard #quarto-dashboard-header .navbar .navbar-author{font-size:.9rem;margin-right:.5em}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-author{margin-left:auto}.quarto-dashboard #quarto-dashboard-header .navbar .navbar-logo{max-height:48px;min-height:30px;object-fit:cover;margin-right:1em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-links{order:9;padding-right:1em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-link-text{margin-left:.25em}.quarto-dashboard #quarto-dashboard-header .navbar .quarto-dashboard-link{padding-right:0em;padding-left:.7em;text-decoration:none;color:#fdfeff}.quarto-dashboard .page-layout-custom .tab-content{padding:0;border:none}.quarto-dashboard-img-contain{height:100%;width:100%;object-fit:contain}@media(max-width: 575.98px){.quarto-dashboard .bslib-grid{grid-template-rows:minmax(1em, max-content) !important}.quarto-dashboard .sidebar-content{height:inherit}.quarto-dashboard .page-layout-custom{min-height:100vh}}.quarto-dashboard.dashboard-toolbar>.page-layout-custom,.quarto-dashboard.dashboard-sidebar>.page-layout-custom{padding:0}.quarto-dashboard .quarto-dashboard-content.quarto-dashboard-pages{padding:0}.quarto-dashboard .callout{margin-bottom:0;margin-top:0}.quarto-dashboard .html-fill-container figure{overflow:hidden}.quarto-dashboard bslib-tooltip .rounded-pill{border:solid #6c757d 1px}.quarto-dashboard bslib-tooltip .rounded-pill .svg{fill:#343a40}.quarto-dashboard .tabset .dashboard-card-no-title .nav-tabs{margin-left:0;margin-right:auto}.quarto-dashboard .tabset .tab-content{border:none}.quarto-dashboard .tabset .card-header .nav-link[role=tab]{margin-top:-6px;padding-top:6px;padding-bottom:6px}.quarto-dashboard .card.valuebox,.quarto-dashboard .card.bslib-value-box{min-height:3rem}.quarto-dashboard .card.valuebox .card-body,.quarto-dashboard .card.bslib-value-box .card-body{padding:0}.quarto-dashboard .bslib-value-box .value-box-value{font-size:clamp(.1em,15cqw,5em)}.quarto-dashboard .bslib-value-box .value-box-showcase .bi{font-size:clamp(.1em,max(18cqw,5.2cqh),5em);text-align:center;height:1em}.quarto-dashboard .bslib-value-box .value-box-showcase .bi::before{vertical-align:1em}.quarto-dashboard .bslib-value-box .value-box-area{margin-top:auto;margin-bottom:auto}.quarto-dashboard .card figure.quarto-float{display:flex;flex-direction:column;align-items:center}.quarto-dashboard .dashboard-scrolling{padding:1em}.quarto-dashboard .full-height{height:100%}.quarto-dashboard .showcase-bottom .value-box-grid{display:grid;grid-template-columns:1fr;grid-template-rows:1fr auto;grid-template-areas:"top" "bottom"}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-showcase{grid-area:bottom;padding:0;margin:0}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-showcase i.bi{font-size:4rem}.quarto-dashboard .showcase-bottom .value-box-grid .value-box-area{grid-area:top}.quarto-dashboard .tab-content{margin-bottom:0}.quarto-dashboard .bslib-card .bslib-navs-card-title{justify-content:stretch;align-items:end}.quarto-dashboard .card-header{display:flex;flex-wrap:wrap;justify-content:space-between}.quarto-dashboard .card-header .card-title{display:flex;flex-direction:column;justify-content:center;margin-bottom:0}.quarto-dashboard .tabset .card-toolbar{margin-bottom:1em}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout{border:none;gap:var(--bslib-spacer, 1rem)}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.main{padding:0}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.sidebar{border-radius:.25rem;border:1px solid rgba(0,0,0,.175)}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.collapse-toggle{display:none}@media(max-width: 767.98px){.quarto-dashboard .bslib-grid>.bslib-sidebar-layout{grid-template-columns:1fr;grid-template-rows:max-content 1fr}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout>.main{grid-column:1;grid-row:2}.quarto-dashboard .bslib-grid>.bslib-sidebar-layout .sidebar{grid-column:1;grid-row:1}}.quarto-dashboard .sidebar-right .sidebar{padding-left:2.5em}.quarto-dashboard .sidebar-right .collapse-toggle{left:2px}.quarto-dashboard .quarto-dashboard .sidebar-right button.collapse-toggle:not(.transitioning){left:unset}.quarto-dashboard aside.sidebar{padding-left:1em;padding-right:1em;background-color:rgba(52,58,64,.25);color:#343a40}.quarto-dashboard .bslib-sidebar-layout>div.main{padding:.7em}.quarto-dashboard .bslib-sidebar-layout button.collapse-toggle{margin-top:.3em}.quarto-dashboard .bslib-sidebar-layout .collapse-toggle{top:0}.quarto-dashboard .bslib-sidebar-layout.sidebar-collapsed:not(.transitioning):not(.sidebar-right) .collapse-toggle{left:2px}.quarto-dashboard .sidebar>section>.h3:first-of-type{margin-top:0em}.quarto-dashboard .sidebar .h3,.quarto-dashboard .sidebar .h4,.quarto-dashboard .sidebar .h5,.quarto-dashboard .sidebar .h6{margin-top:.5em}.quarto-dashboard .sidebar form{flex-direction:column;align-items:start;margin-bottom:1em}.quarto-dashboard .sidebar form div[class*=oi-][class$=-input]{flex-direction:column}.quarto-dashboard .sidebar form[class*=oi-][class$=-toggle]{flex-direction:row-reverse;align-items:center;justify-content:start}.quarto-dashboard .sidebar form input[type=range]{margin-top:.5em;margin-right:.8em;margin-left:1em}.quarto-dashboard .sidebar label{width:fit-content}.quarto-dashboard .sidebar .card-body{margin-bottom:2em}.quarto-dashboard .sidebar .shiny-input-container{margin-bottom:1em}.quarto-dashboard .sidebar .shiny-options-group{margin-top:0}.quarto-dashboard .sidebar .control-label{margin-bottom:.3em}.quarto-dashboard .card .card-body .quarto-layout-row{align-items:stretch}.quarto-dashboard .toolbar{font-size:.9em;display:flex;flex-direction:row;border-top:solid 1px #bcbfc0;padding:1em;flex-wrap:wrap;background-color:rgba(52,58,64,.25)}.quarto-dashboard .toolbar .cell-output-display{display:flex}.quarto-dashboard .toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .toolbar>*:last-child{margin-right:0}.quarto-dashboard .toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .toolbar .shiny-input-container{padding-bottom:0;margin-bottom:0}.quarto-dashboard .toolbar .shiny-input-container>*{flex-shrink:0;flex-grow:0}.quarto-dashboard .toolbar .form-group.shiny-input-container:not([role=group])>label{margin-bottom:0}.quarto-dashboard .toolbar .shiny-input-container.no-baseline{align-items:start;padding-top:6px}.quarto-dashboard .toolbar .shiny-input-container{display:flex;align-items:baseline}.quarto-dashboard .toolbar .shiny-input-container label{padding-right:.4em}.quarto-dashboard .toolbar .shiny-input-container .bslib-input-switch{margin-top:6px}.quarto-dashboard .toolbar input[type=text]{line-height:1;width:inherit}.quarto-dashboard .toolbar .input-daterange{width:inherit}.quarto-dashboard .toolbar .input-daterange input[type=text]{height:2.4em;width:10em}.quarto-dashboard .toolbar .input-daterange .input-group-addon{height:auto;padding:0;margin-left:-5px !important;margin-right:-5px}.quarto-dashboard .toolbar .input-daterange .input-group-addon .input-group-text{padding-top:0;padding-bottom:0;height:100%}.quarto-dashboard .toolbar span.irs.irs--shiny{width:10em}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-line{top:9px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-min,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-max,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-from,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-to,.quarto-dashboard .toolbar span.irs.irs--shiny .irs-single{top:20px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-bar{top:8px}.quarto-dashboard .toolbar span.irs.irs--shiny .irs-handle{top:0px}.quarto-dashboard .toolbar .shiny-input-checkboxgroup>label{margin-top:6px}.quarto-dashboard .toolbar .shiny-input-checkboxgroup>.shiny-options-group{margin-top:0;align-items:baseline}.quarto-dashboard .toolbar .shiny-input-radiogroup>label{margin-top:6px}.quarto-dashboard .toolbar .shiny-input-radiogroup>.shiny-options-group{align-items:baseline;margin-top:0}.quarto-dashboard .toolbar .shiny-input-radiogroup>.shiny-options-group>.radio{margin-right:.3em}.quarto-dashboard .toolbar .form-select{padding-top:.2em;padding-bottom:.2em}.quarto-dashboard .toolbar .shiny-input-select{min-width:6em}.quarto-dashboard .toolbar div.checkbox{margin-bottom:0px}.quarto-dashboard .toolbar>.checkbox:first-child{margin-top:6px}.quarto-dashboard .toolbar form{width:fit-content}.quarto-dashboard .toolbar form label{padding-top:.2em;padding-bottom:.2em;width:fit-content}.quarto-dashboard .toolbar form input[type=date]{width:fit-content}.quarto-dashboard .toolbar form input[type=color]{width:3em}.quarto-dashboard .toolbar form button{padding:.4em}.quarto-dashboard .toolbar form select{width:fit-content}.quarto-dashboard .toolbar>*{font-size:.9em;flex-grow:0}.quarto-dashboard .toolbar .shiny-input-container label{margin-bottom:1px}.quarto-dashboard .toolbar-bottom{margin-top:1em;margin-bottom:0 !important;order:2}.quarto-dashboard .quarto-dashboard-content>.dashboard-toolbar-container>.toolbar-content>.tab-content>.tab-pane>*:not(.bslib-sidebar-layout){padding:1em}.quarto-dashboard .quarto-dashboard-content>.dashboard-toolbar-container>.toolbar-content>*:not(.tab-content){padding:1em}.quarto-dashboard .quarto-dashboard-content>.tab-content>.dashboard-page>.dashboard-toolbar-container>.toolbar-content,.quarto-dashboard .quarto-dashboard-content>.tab-content>.dashboard-page:not(.dashboard-sidebar-container)>*:not(.dashboard-toolbar-container){padding:1em}.quarto-dashboard .toolbar-content{padding:0}.quarto-dashboard .quarto-dashboard-content.quarto-dashboard-pages .tab-pane>.dashboard-toolbar-container .toolbar{border-radius:0;margin-bottom:0}.quarto-dashboard .dashboard-toolbar-container.toolbar-toplevel .toolbar{border-bottom:1px solid rgba(0,0,0,.175)}.quarto-dashboard .dashboard-toolbar-container.toolbar-toplevel .toolbar-bottom{margin-top:0}.quarto-dashboard .dashboard-toolbar-container:not(.toolbar-toplevel) .toolbar{margin-bottom:1em;border-top:none;border-radius:.25rem;border:1px solid rgba(0,0,0,.175)}.quarto-dashboard .vega-embed.has-actions details{width:1.7em;height:2em;position:absolute !important;top:0;right:0}.quarto-dashboard .dashboard-toolbar-container{padding:0}.quarto-dashboard .card .card-header p:last-child,.quarto-dashboard .card .card-footer p:last-child{margin-bottom:0}.quarto-dashboard .card .card-body>.h4:first-child{margin-top:0}.quarto-dashboard .card .card-body{z-index:4}@media(max-width: 767.98px){.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_length,.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_info,.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_paginate{text-align:initial}.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_filter{text-align:right}.quarto-dashboard .card .card-body .itables div.dataTables_wrapper div.dataTables_paginate ul.pagination{justify-content:initial}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;padding-top:0}.quarto-dashboard .card .card-body .itables .dataTables_wrapper table{flex-shrink:0}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons{margin-bottom:.5em;margin-left:auto;width:fit-content;float:right}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons.btn-group{background:#fff;border:none}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons .btn-secondary{background-color:#fff;background-image:none;border:solid #dee2e6 1px;padding:.2em .7em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dt-buttons .btn span{font-size:.8em;color:#343a40}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{margin-left:.5em;margin-bottom:.5em;padding-top:0}@media(min-width: 768px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{font-size:.875em}}@media(max-width: 767.98px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_info{font-size:.8em}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_filter{margin-bottom:.5em;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_filter input[type=search]{padding:1px 5px 1px 5px;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_length{flex-basis:1 1 50%;margin-bottom:.5em;font-size:.875em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_length select{padding:.4em 3em .4em .5em;font-size:.875em;margin-left:.2em;margin-right:.2em}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate{flex-shrink:0}@media(min-width: 768px){.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate{margin-left:auto}}.quarto-dashboard .card .card-body .itables .dataTables_wrapper .dataTables_paginate ul.pagination .paginate_button .page-link{font-size:.8em}.quarto-dashboard .card .card-footer{font-size:.9em}.quarto-dashboard .card .card-toolbar{display:flex;flex-grow:1;flex-direction:row;width:100%;flex-wrap:wrap}.quarto-dashboard .card .card-toolbar>*{font-size:.8em;flex-grow:0}.quarto-dashboard .card .card-toolbar>.card-title{font-size:1em;flex-grow:1;align-self:flex-start;margin-top:.1em}.quarto-dashboard .card .card-toolbar .cell-output-display{display:flex}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .card .card-toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card .card-toolbar>*:last-child{margin-right:0}.quarto-dashboard .card .card-toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .card .card-toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .card .card-toolbar form{width:fit-content}.quarto-dashboard .card .card-toolbar form label{padding-top:.2em;padding-bottom:.2em;width:fit-content}.quarto-dashboard .card .card-toolbar form input[type=date]{width:fit-content}.quarto-dashboard .card .card-toolbar form input[type=color]{width:3em}.quarto-dashboard .card .card-toolbar form button{padding:.4em}.quarto-dashboard .card .card-toolbar form select{width:fit-content}.quarto-dashboard .card .card-toolbar .cell-output-display{display:flex}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:.5em;margin-bottom:.5em;width:inherit}.quarto-dashboard .card .card-toolbar .shiny-input-container>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card .card-toolbar>*:last-child{margin-right:0}.quarto-dashboard .card .card-toolbar>*>*{margin-right:1em;align-items:baseline}.quarto-dashboard .card .card-toolbar>*>*>a{text-decoration:none;margin-top:auto;margin-bottom:auto}.quarto-dashboard .card .card-toolbar .shiny-input-container{padding-bottom:0;margin-bottom:0}.quarto-dashboard .card .card-toolbar .shiny-input-container>*{flex-shrink:0;flex-grow:0}.quarto-dashboard .card .card-toolbar .form-group.shiny-input-container:not([role=group])>label{margin-bottom:0}.quarto-dashboard .card .card-toolbar .shiny-input-container.no-baseline{align-items:start;padding-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-container{display:flex;align-items:baseline}.quarto-dashboard .card .card-toolbar .shiny-input-container label{padding-right:.4em}.quarto-dashboard .card .card-toolbar .shiny-input-container .bslib-input-switch{margin-top:6px}.quarto-dashboard .card .card-toolbar input[type=text]{line-height:1;width:inherit}.quarto-dashboard .card .card-toolbar .input-daterange{width:inherit}.quarto-dashboard .card .card-toolbar .input-daterange input[type=text]{height:2.4em;width:10em}.quarto-dashboard .card .card-toolbar .input-daterange .input-group-addon{height:auto;padding:0;margin-left:-5px !important;margin-right:-5px}.quarto-dashboard .card .card-toolbar .input-daterange .input-group-addon .input-group-text{padding-top:0;padding-bottom:0;height:100%}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny{width:10em}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-line{top:9px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-min,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-max,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-from,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-to,.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-single{top:20px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-bar{top:8px}.quarto-dashboard .card .card-toolbar span.irs.irs--shiny .irs-handle{top:0px}.quarto-dashboard .card .card-toolbar .shiny-input-checkboxgroup>label{margin-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-checkboxgroup>.shiny-options-group{margin-top:0;align-items:baseline}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>label{margin-top:6px}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>.shiny-options-group{align-items:baseline;margin-top:0}.quarto-dashboard .card .card-toolbar .shiny-input-radiogroup>.shiny-options-group>.radio{margin-right:.3em}.quarto-dashboard .card .card-toolbar .form-select{padding-top:.2em;padding-bottom:.2em}.quarto-dashboard .card .card-toolbar .shiny-input-select{min-width:6em}.quarto-dashboard .card .card-toolbar div.checkbox{margin-bottom:0px}.quarto-dashboard .card .card-toolbar>.checkbox:first-child{margin-top:6px}.quarto-dashboard .card-body>table>thead{border-top:none}.quarto-dashboard .card-body>.table>:not(caption)>*>*{background-color:#fff}.tableFloatingHeaderOriginal{background-color:#fff;position:sticky !important;top:0 !important}.dashboard-data-table{margin-top:-1px}div.value-box-area span.observablehq--number{font-size:calc(clamp(.1em,15cqw,5em)*1.25);line-height:1.2;color:inherit;font-family:var(--bs-body-font-family)}.quarto-listing{padding-bottom:1em}.listing-pagination{padding-top:.5em}ul.pagination{float:right;padding-left:8px;padding-top:.5em}ul.pagination li{padding-right:.75em}ul.pagination li.disabled a,ul.pagination li.active a{color:#fff;text-decoration:none}ul.pagination li:last-of-type{padding-right:0}.listing-actions-group{display:flex}.quarto-listing-filter{margin-bottom:1em;width:200px;margin-left:auto}.quarto-listing-sort{margin-bottom:1em;margin-right:auto;width:auto}.quarto-listing-sort .input-group-text{font-size:.8em}.input-group-text{border-right:none}.quarto-listing-sort select.form-select{font-size:.8em}.listing-no-matching{text-align:center;padding-top:2em;padding-bottom:3em;font-size:1em}#quarto-margin-sidebar .quarto-listing-category{padding-top:0;font-size:1rem}#quarto-margin-sidebar .quarto-listing-category-title{cursor:pointer;font-weight:600;font-size:1rem}.quarto-listing-category .category{cursor:pointer}.quarto-listing-category .category.active{font-weight:600}.quarto-listing-category.category-cloud{display:flex;flex-wrap:wrap;align-items:baseline}.quarto-listing-category.category-cloud .category{padding-right:5px}.quarto-listing-category.category-cloud .category-cloud-1{font-size:.75em}.quarto-listing-category.category-cloud .category-cloud-2{font-size:.95em}.quarto-listing-category.category-cloud .category-cloud-3{font-size:1.15em}.quarto-listing-category.category-cloud .category-cloud-4{font-size:1.35em}.quarto-listing-category.category-cloud .category-cloud-5{font-size:1.55em}.quarto-listing-category.category-cloud .category-cloud-6{font-size:1.75em}.quarto-listing-category.category-cloud .category-cloud-7{font-size:1.95em}.quarto-listing-category.category-cloud .category-cloud-8{font-size:2.15em}.quarto-listing-category.category-cloud .category-cloud-9{font-size:2.35em}.quarto-listing-category.category-cloud .category-cloud-10{font-size:2.55em}.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-1{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-2{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-3{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-3{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-4{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-4{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-5{grid-template-columns:repeat(5, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-5{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-5{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-6{grid-template-columns:repeat(6, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-6{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-6{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-7{grid-template-columns:repeat(7, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-7{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-7{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-8{grid-template-columns:repeat(8, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-8{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-8{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-9{grid-template-columns:repeat(9, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-9{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-9{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-10{grid-template-columns:repeat(10, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-10{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-10{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-11{grid-template-columns:repeat(11, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-11{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-11{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-12{grid-template-columns:repeat(12, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-12{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-12{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-grid{gap:1.5em}.quarto-grid-item.borderless{border:none}.quarto-grid-item.borderless .listing-categories .listing-category:last-of-type,.quarto-grid-item.borderless .listing-categories .listing-category:first-of-type{padding-left:0}.quarto-grid-item.borderless .listing-categories .listing-category{border:0}.quarto-grid-link{text-decoration:none;color:inherit}.quarto-grid-link:hover{text-decoration:none;color:inherit}.quarto-grid-item h5.title,.quarto-grid-item .title.h5{margin-top:0;margin-bottom:0}.quarto-grid-item .card-footer{display:flex;justify-content:space-between;font-size:.8em}.quarto-grid-item .card-footer p{margin-bottom:0}.quarto-grid-item p.card-img-top{margin-bottom:0}.quarto-grid-item p.card-img-top>img{object-fit:cover}.quarto-grid-item .card-other-values{margin-top:.5em;font-size:.8em}.quarto-grid-item .card-other-values tr{margin-bottom:.5em}.quarto-grid-item .card-other-values tr>td:first-of-type{font-weight:600;padding-right:1em;padding-left:1em;vertical-align:top}.quarto-grid-item div.post-contents{display:flex;flex-direction:column;text-decoration:none;height:100%}.quarto-grid-item .listing-item-img-placeholder{background-color:rgba(52,58,64,.25);flex-shrink:0}.quarto-grid-item .card-attribution{padding-top:1em;display:flex;gap:1em;text-transform:uppercase;color:#6c757d;font-weight:500;flex-grow:10;align-items:flex-end}.quarto-grid-item .description{padding-bottom:1em}.quarto-grid-item .card-attribution .date{align-self:flex-end}.quarto-grid-item .card-attribution.justify{justify-content:space-between}.quarto-grid-item .card-attribution.start{justify-content:flex-start}.quarto-grid-item .card-attribution.end{justify-content:flex-end}.quarto-grid-item .card-title{margin-bottom:.1em}.quarto-grid-item .card-subtitle{padding-top:.25em}.quarto-grid-item .card-text{font-size:.9em}.quarto-grid-item .listing-reading-time{padding-bottom:.25em}.quarto-grid-item .card-text-small{font-size:.8em}.quarto-grid-item .card-subtitle.subtitle{font-size:.9em;font-weight:600;padding-bottom:.5em}.quarto-grid-item .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}.quarto-grid-item .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}.quarto-grid-item.card-right{text-align:right}.quarto-grid-item.card-right .listing-categories{justify-content:flex-end}.quarto-grid-item.card-left{text-align:left}.quarto-grid-item.card-center{text-align:center}.quarto-grid-item.card-center .listing-description{text-align:justify}.quarto-grid-item.card-center .listing-categories{justify-content:center}table.quarto-listing-table td.image{padding:0px}table.quarto-listing-table td.image img{width:100%;max-width:50px;object-fit:contain}table.quarto-listing-table a{text-decoration:none;word-break:keep-all}table.quarto-listing-table th a{color:inherit}table.quarto-listing-table th a.asc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table th a.desc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table.table-hover td{cursor:pointer}.quarto-post.image-left{flex-direction:row}.quarto-post.image-right{flex-direction:row-reverse}@media(max-width: 767.98px){.quarto-post.image-right,.quarto-post.image-left{gap:0em;flex-direction:column}.quarto-post .metadata{padding-bottom:1em;order:2}.quarto-post .body{order:1}.quarto-post .thumbnail{order:3}}.list.quarto-listing-default div:last-of-type{border-bottom:none}@media(min-width: 992px){.quarto-listing-container-default{margin-right:2em}}div.quarto-post{display:flex;gap:2em;margin-bottom:1.5em;border-bottom:1px solid #dee2e6}@media(max-width: 767.98px){div.quarto-post{padding-bottom:1em}}div.quarto-post .metadata{flex-basis:20%;flex-grow:0;margin-top:.2em;flex-shrink:10}div.quarto-post .thumbnail{flex-basis:30%;flex-grow:0;flex-shrink:0}div.quarto-post .thumbnail img{margin-top:.4em;width:100%;object-fit:cover}div.quarto-post .body{flex-basis:45%;flex-grow:1;flex-shrink:0}div.quarto-post .body h3.listing-title,div.quarto-post .body .listing-title.h3{margin-top:0px;margin-bottom:0px;border-bottom:none}div.quarto-post .body .listing-subtitle{font-size:.875em;margin-bottom:.5em;margin-top:.2em}div.quarto-post .body .description{font-size:.9em}div.quarto-post .body pre code{white-space:pre-wrap}div.quarto-post a{color:#343a40;text-decoration:none}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";flex-basis:33%}div.quarto-post .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}div.quarto-post .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}div.quarto-post .listing-description{margin-bottom:.5em}div.quarto-about-jolla{display:flex !important;flex-direction:column;align-items:center;margin-top:10%;padding-bottom:1em}div.quarto-about-jolla .about-image{object-fit:cover;margin-left:auto;margin-right:auto;margin-bottom:1.5em}div.quarto-about-jolla img.round{border-radius:50%}div.quarto-about-jolla img.rounded{border-radius:10px}div.quarto-about-jolla .quarto-title h1.title,div.quarto-about-jolla .quarto-title .title.h1{text-align:center}div.quarto-about-jolla .quarto-title .description{text-align:center}div.quarto-about-jolla h2,div.quarto-about-jolla .h2{border-bottom:none}div.quarto-about-jolla .about-sep{width:60%}div.quarto-about-jolla main{text-align:center}div.quarto-about-jolla .about-links{display:flex}@media(min-width: 992px){div.quarto-about-jolla .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-jolla .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-jolla .about-link{color:#626d78;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-jolla .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-jolla .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-jolla .about-link:hover{color:#2761e3}div.quarto-about-jolla .about-link i.bi{margin-right:.15em}div.quarto-about-solana{display:flex !important;flex-direction:column;padding-top:3em !important;padding-bottom:1em}div.quarto-about-solana .about-entity{display:flex !important;align-items:start;justify-content:space-between}@media(min-width: 992px){div.quarto-about-solana .about-entity{flex-direction:row}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity{flex-direction:column-reverse;align-items:center;text-align:center}}div.quarto-about-solana .about-entity .entity-contents{display:flex;flex-direction:column}@media(max-width: 767.98px){div.quarto-about-solana .about-entity .entity-contents{width:100%}}div.quarto-about-solana .about-entity .about-image{object-fit:cover}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-image{margin-bottom:1.5em}}div.quarto-about-solana .about-entity img.round{border-radius:50%}div.quarto-about-solana .about-entity img.rounded{border-radius:10px}div.quarto-about-solana .about-entity .about-links{display:flex;justify-content:left;padding-bottom:1.2em}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-solana .about-entity .about-link{color:#626d78;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-solana .about-entity .about-link:hover{color:#2761e3}div.quarto-about-solana .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-solana .about-contents{padding-right:1.5em;flex-basis:0;flex-grow:1}div.quarto-about-solana .about-contents main.content{margin-top:0}div.quarto-about-solana .about-contents h2,div.quarto-about-solana .about-contents .h2{border-bottom:none}div.quarto-about-trestles{display:flex !important;flex-direction:row;padding-top:3em !important;padding-bottom:1em}@media(max-width: 991.98px){div.quarto-about-trestles{flex-direction:column;padding-top:0em !important}}div.quarto-about-trestles .about-entity{display:flex !important;flex-direction:column;align-items:center;text-align:center;padding-right:1em}@media(min-width: 992px){div.quarto-about-trestles .about-entity{flex:0 0 42%}}div.quarto-about-trestles .about-entity .about-image{object-fit:cover;margin-bottom:1.5em}div.quarto-about-trestles .about-entity img.round{border-radius:50%}div.quarto-about-trestles .about-entity img.rounded{border-radius:10px}div.quarto-about-trestles .about-entity .about-links{display:flex;justify-content:center}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-trestles .about-entity .about-link{color:#626d78;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-trestles .about-entity .about-link:hover{color:#2761e3}div.quarto-about-trestles .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-trestles .about-contents{flex-basis:0;flex-grow:1}div.quarto-about-trestles .about-contents h2,div.quarto-about-trestles .about-contents .h2{border-bottom:none}@media(min-width: 992px){div.quarto-about-trestles .about-contents{border-left:solid 1px #dee2e6;padding-left:1.5em}}div.quarto-about-trestles .about-contents main.content{margin-top:0}div.quarto-about-marquee{padding-bottom:1em}div.quarto-about-marquee .about-contents{display:flex;flex-direction:column}div.quarto-about-marquee .about-image{max-height:550px;margin-bottom:1.5em;object-fit:cover}div.quarto-about-marquee img.round{border-radius:50%}div.quarto-about-marquee img.rounded{border-radius:10px}div.quarto-about-marquee h2,div.quarto-about-marquee .h2{border-bottom:none}div.quarto-about-marquee .about-links{display:flex;justify-content:center;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-marquee .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-marquee .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-marquee .about-link{color:#626d78;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-marquee .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-marquee .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-marquee .about-link:hover{color:#2761e3}div.quarto-about-marquee .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-marquee .about-link{border:none}}div.quarto-about-broadside{display:flex;flex-direction:column;padding-bottom:1em}div.quarto-about-broadside .about-main{display:flex !important;padding-top:0 !important}@media(min-width: 992px){div.quarto-about-broadside .about-main{flex-direction:row;align-items:flex-start}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main{flex-direction:column}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main .about-entity{flex-shrink:0;width:100%;height:450px;margin-bottom:1.5em;background-size:cover;background-repeat:no-repeat}}@media(min-width: 992px){div.quarto-about-broadside .about-main .about-entity{flex:0 10 50%;margin-right:1.5em;width:100%;height:100%;background-size:100%;background-repeat:no-repeat}}div.quarto-about-broadside .about-main .about-contents{padding-top:14px;flex:0 0 50%}div.quarto-about-broadside h2,div.quarto-about-broadside .h2{border-bottom:none}div.quarto-about-broadside .about-sep{margin-top:1.5em;width:60%;align-self:center}div.quarto-about-broadside .about-links{display:flex;justify-content:center;column-gap:20px;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-broadside .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-broadside .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-broadside .about-link{color:#626d78;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-broadside .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-broadside .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-broadside .about-link:hover{color:#2761e3}div.quarto-about-broadside .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-broadside .about-link{border:none}}.tippy-box[data-theme~=quarto]{background-color:#fff;border:solid 1px #dee2e6;border-radius:.25rem;color:#343a40;font-size:.875rem}.tippy-box[data-theme~=quarto]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=quarto]>.tippy-arrow:after,.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=quarto]>.tippy-arrow:after{border-color:rgba(0,0,0,0);border-style:solid}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-6px}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-6px}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-6px}.tippy-box[data-placement^=left]>.tippy-arrow:before{right:-6px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:after{border-top-color:#dee2e6;border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:#dee2e6;border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:15px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:after{border-left-color:#dee2e6;border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:#dee2e6}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow{fill:#343a40}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.top-right{position:absolute;top:1em;right:1em}.visually-hidden{border:0;clip:rect(0 0 0 0);height:auto;margin:0;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}figure.figure{display:block}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p,.quarto-figure-left>figure>div{text-align:left}.quarto-figure-center>figure>p,.quarto-figure-center>figure>div{text-align:center}.quarto-figure-right>figure>p,.quarto-figure-right>figure>div{text-align:right}.quarto-figure>figure>div.cell-annotation,.quarto-figure>figure>div code{text-align:left}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption.quarto-float-caption-bottom{margin-bottom:.5em}figure>figcaption.quarto-float-caption-top{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link{position:absolute;top:.6em;right:.5em}div[id^=tbl-]>.anchorjs-link{position:absolute;top:.7em;right:.3em}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,table.table{margin-top:.5rem;margin-bottom:.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-top{margin-top:.5rem;margin-bottom:.25rem;text-align:center}figure.quarto-float-tbl figcaption.quarto-float-caption-bottom{padding-top:.25rem;margin-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:#6c757d}details>summary>p:only-child{display:inline}pre.sourceCode,code.sourceCode{position:relative}dd code:not(.sourceCode),p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.footnote-back{margin-left:.2em}.tippy-content{overflow-x:auto}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x),.knitsql-table:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}a{text-underline-offset:3px}div.ansi-escaped-output{font-family:monospace;display:block}/*! +* +* ansi colors from IPython notebook's +* +* we also add `bright-[color]-` synonyms for the `-[color]-intense` classes since +* that seems to be what ansi_up emits +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-black,.ansi-bright-black-fg{color:#282c36}.ansi-black-intense-black,.ansi-bright-black-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-red,.ansi-bright-red-fg{color:#b22b31}.ansi-red-intense-red,.ansi-bright-red-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-green,.ansi-bright-green-fg{color:#007427}.ansi-green-intense-green,.ansi-bright-green-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-yellow,.ansi-bright-yellow-fg{color:#b27d12}.ansi-yellow-intense-yellow,.ansi-bright-yellow-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-blue,.ansi-bright-blue-fg{color:#0065ca}.ansi-blue-intense-blue,.ansi-bright-blue-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-magenta,.ansi-bright-magenta-fg{color:#a03196}.ansi-magenta-intense-magenta,.ansi-bright-magenta-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-cyan,.ansi-bright-cyan-fg{color:#258f8f}.ansi-cyan-intense-cyan,.ansi-bright-cyan-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-white,.ansi-bright-white-fg{color:#a1a6b2}.ansi-white-intense-white,.ansi-bright-white-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #fff;--quarto-body-color: #343a40;--quarto-text-muted: #6c757d;--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.25rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:rgba(0,0,0,0)}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}.code-annotation-tip-content{word-wrap:break-word}.code-annotation-container-hidden{display:none !important}dl.code-annotation-container-grid{display:grid;grid-template-columns:min-content auto}dl.code-annotation-container-grid dt{grid-column:1}dl.code-annotation-container-grid dd{grid-column:2}pre.sourceCode.code-annotation-code{padding-right:0}code.sourceCode .code-annotation-anchor{z-index:100;position:relative;float:right;background-color:rgba(0,0,0,0)}input[type=checkbox]{margin-right:.5ch}:root{--mermaid-bg-color: #fff;--mermaid-edge-color: #343a40;--mermaid-node-fg-color: #343a40;--mermaid-fg-color: #343a40;--mermaid-fg-color--lighter: #4b545c;--mermaid-fg-color--lightest: #626d78;--mermaid-font-family: Source Sans Pro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;--mermaid-label-bg-color: #fff;--mermaid-label-fg-color: #2780e3;--mermaid-node-bg-color: rgba(39, 128, 227, 0.1);--mermaid-node-fg-color: #343a40}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:rgba(0,0,0,0);z-index:3}.code-copy-button:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml,')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}ul>li:not(:has(>p))>ul,ol>li:not(:has(>p))>ul,ul>li:not(:has(>p))>ol,ol>li:not(:has(>p))>ol{margin-bottom:0}ul>li:not(:has(>p))>ul>li:has(>p),ol>li:not(:has(>p))>ul>li:has(>p),ul>li:not(:has(>p))>ol>li:has(>p),ol>li:not(:has(>p))>ol>li:has(>p){margin-top:1rem}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] minmax(50px, 100px) [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc(1250px - 3em)) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(1000px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(800px - 3em)) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc(750px - 3em)) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left .page-columns.page-full>*,.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right .page-columns.page-full>*,.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;opacity:.999}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;opacity:.999}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse,#quarto-content.page-columns #quarto-margin-sidebar.collapsing,#quarto-content.page-columns #quarto-sidebar.collapsing{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#f8f9fa;z-index:998;opacity:.999;margin-bottom:1em}.zindex-content{z-index:998;opacity:.999}.zindex-modal{z-index:1055;opacity:.999}.zindex-over-content{z-index:999;opacity:.999}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside:not(.footnotes):not(.sidebar),.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside:not(.footnotes):not(.sidebar),.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;opacity:.999}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}#quarto-sidebar-toc-left{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{color:inherit;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{margin-top:0}main.content>section:first-of-type>h2:first-child,main.content>section:first-of-type>.h2:first-child{margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3{font-weight:600}h3,.h3,h4,.h4{opacity:.9;margin-top:1.5rem}h5,.h5,h6,.h6{opacity:.9}.header-section-number{color:#6d7a86}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,.figure-caption,.subfigure-caption,.table-caption,figcaption,caption{font-size:.9rem;color:#6d7a86}.quarto-layout-cell[data-ref-parent] caption{color:#6d7a86}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#6d7a86;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse):first-child{padding-bottom:.5em;display:block}.column-margin.column-container>*:not(.collapse):not(:first-child){padding-top:.5em;padding-bottom:.5em;display:block}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.nav-tabs .nav-item{margin-top:1px;cursor:pointer}.tab-content{margin-top:0px;border-left:#dee2e6 1px solid;border-right:#dee2e6 1px solid;border-bottom:#dee2e6 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:0}.tab-pane>p:nth-child(1){padding-top:0}.tab-pane>p:last-child{margin-bottom:0}.tab-pane>pre:last-child{margin-bottom:0}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(233,236,239,.65);border:1px solid rgba(233,236,239,.65);border-radius:.25rem}pre.sourceCode{background-color:rgba(0,0,0,0)}pre.sourceCode{border:none;font-size:.875em;overflow:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#6d7a86}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p pre code:not(.sourceCode),li pre code:not(.sourceCode),pre code:not(.sourceCode){background-color:initial}p code:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:#f8f9fa;padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode),nav td code:not(.sourceCode){background-color:rgba(0,0,0,0);padding:0}td code:not(.sourceCode){white-space:pre-wrap}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:#6c757d;background-color:rgba(0,0,0,0);transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}figure .quarto-notebook-link{margin-top:.5em}.quarto-notebook-link{font-size:.75em;color:#6c757d;margin-bottom:1em;text-decoration:none;display:block}.quarto-notebook-link:hover{text-decoration:underline;color:#2761e3}.quarto-notebook-link::before{display:inline-block;height:.75rem;width:.75rem;margin-bottom:0em;margin-right:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}.toc-actions i.bi,.quarto-code-links i.bi,.quarto-other-links i.bi,.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em;font-size:.8rem}.quarto-other-links-text-target .quarto-code-links i.bi,.quarto-other-links-text-target .quarto-other-links i.bi{margin-right:.2em}.quarto-other-formats-text-target .quarto-alternate-formats i.bi{margin-right:.1em}.toc-actions i.bi.empty,.quarto-code-links i.bi.empty,.quarto-other-links i.bi.empty,.quarto-alternate-notebooks i.bi.empty,.quarto-alternate-formats i.bi.empty{padding-left:1em}.quarto-notebook h2,.quarto-notebook .h2{border-bottom:none}.quarto-notebook .cell-container{display:flex}.quarto-notebook .cell-container .cell{flex-grow:4}.quarto-notebook .cell-container .cell-decorator{padding-top:1.5em;padding-right:1em;text-align:right}.quarto-notebook .cell-container.code-fold .cell-decorator{padding-top:3em}.quarto-notebook .cell-code code{white-space:pre-wrap}.quarto-notebook .cell .cell-output-stderr pre code,.quarto-notebook .cell .cell-output-stdout pre code{white-space:pre-wrap;overflow-wrap:anywhere}.toc-actions,.quarto-alternate-formats,.quarto-other-links,.quarto-code-links,.quarto-alternate-notebooks{padding-left:0em}.sidebar .toc-actions a,.sidebar .quarto-alternate-formats a,.sidebar .quarto-other-links a,.sidebar .quarto-code-links a,.sidebar .quarto-alternate-notebooks a,.sidebar nav[role=doc-toc] a{text-decoration:none}.sidebar .toc-actions a:hover,.sidebar .quarto-other-links a:hover,.sidebar .quarto-code-links a:hover,.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#2761e3}.sidebar .toc-actions h2,.sidebar .toc-actions .h2,.sidebar .quarto-code-links h2,.sidebar .quarto-code-links .h2,.sidebar .quarto-other-links h2,.sidebar .quarto-other-links .h2,.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2,.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-weight:500;margin-bottom:.2rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .toc-actions>h2,.sidebar .toc-actions>.h2,.sidebar .quarto-code-links>h2,.sidebar .quarto-code-links>.h2,.sidebar .quarto-other-links>h2,.sidebar .quarto-other-links>.h2,.sidebar .quarto-alternate-notebooks>h2,.sidebar .quarto-alternate-notebooks>.h2,.sidebar .quarto-alternate-formats>h2,.sidebar .quarto-alternate-formats>.h2{font-size:.8rem}.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #e9ecef;padding-left:.6rem}.sidebar .toc-actions h2>ul a,.sidebar .toc-actions .h2>ul a,.sidebar .quarto-code-links h2>ul a,.sidebar .quarto-code-links .h2>ul a,.sidebar .quarto-other-links h2>ul a,.sidebar .quarto-other-links .h2>ul a,.sidebar .quarto-alternate-notebooks h2>ul a,.sidebar .quarto-alternate-notebooks .h2>ul a,.sidebar .quarto-alternate-formats h2>ul a,.sidebar .quarto-alternate-formats .h2>ul a{border-left:none;padding-left:.6rem}.sidebar .toc-actions ul a:empty,.sidebar .quarto-code-links ul a:empty,.sidebar .quarto-other-links ul a:empty,.sidebar .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .toc-actions ul,.sidebar .quarto-code-links ul,.sidebar .quarto-other-links ul,.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul{padding-left:0;list-style:none}.sidebar nav[role=doc-toc] ul{list-style:none;padding-left:0;list-style:none}.sidebar nav[role=doc-toc]>ul{margin-left:.45em}.quarto-margin-sidebar nav[role=doc-toc]{padding-left:.5em}.sidebar .toc-actions>ul,.sidebar .quarto-code-links>ul,.sidebar .quarto-other-links>ul,.sidebar .quarto-alternate-notebooks>ul,.sidebar .quarto-alternate-formats>ul{font-size:.8rem}.sidebar nav[role=doc-toc]>ul{font-size:.875rem}.sidebar .toc-actions ul li a,.sidebar .quarto-code-links ul li a,.sidebar .quarto-other-links ul li a,.sidebar .quarto-alternate-notebooks ul li a,.sidebar .quarto-alternate-formats ul li a,.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>a.active,.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #2761e3;color:#2761e3 !important}.sidebar nav[role=doc-toc] ul>li>a:hover,.sidebar nav[role=doc-toc] ul>li>ul>li>a:hover{color:#2761e3 !important}kbd,.kbd{color:#343a40;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}.quarto-appendix-contents div.hanging-indent{margin-left:0em}.quarto-appendix-contents div.hanging-indent div.csl-entry{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.25rem;overflow-wrap:break-word}.callout .callout-title-container{overflow-wrap:anywhere}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout:not(.no-icon).callout-titled.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-titled>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em}.callout.callout-style-default .callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default .callout-body>:first-child{padding-top:.5rem;margin-top:0}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-titled .callout-body>:last-child:not(.sourceCode),.callout.callout-titled .callout-body>div>:last-child:not(.sourceCode){padding-bottom:.5rem;margin-bottom:0}.callout:not(.callout-titled) .callout-body>:first-child,.callout:not(.callout-titled) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-titled) .callout-body>:last-child,.callout:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-title-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:#6c757d}div.callout.callout-style-default>.callout-header{background-color:#6c757d}div.callout-note.callout{border-left-color:#2780e3}div.callout-note.callout-style-default>.callout-header{background-color:#e9f2fc}div.callout-note:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-tip.callout{border-left-color:#3fb618}div.callout-tip.callout-style-default>.callout-header{background-color:#ecf8e8}div.callout-tip:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-warning.callout{border-left-color:#ff7518}div.callout-warning.callout-style-default>.callout-header{background-color:#fff1e8}div.callout-warning:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-caution.callout{border-left-color:#f0ad4e}div.callout-caution.callout-style-default>.callout-header{background-color:#fef7ed}div.callout-caution:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-important.callout{border-left-color:#ff0039}div.callout-important.callout-style-default>.callout-header{background-color:#ffe6eb}div.callout-important:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml,')}.quarto-toggle-container{display:flex;align-items:center}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.sidebar-navigation{padding-left:20px}.navbar{background-color:#2780e3;color:#fdfeff}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:#fafafa}#quarto-content .quarto-sidebar-toggle-title{color:#343a40}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}@media(max-width: 767.98px){.sidebar-menu-container{padding-bottom:5em}}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml,')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml,')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .footnotes ol{margin-left:.5em}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{--bs-btn-color: #cacccd;--bs-btn-bg: #343a40;--bs-btn-border-color: #343a40;--bs-btn-hover-color: #cacccd;--bs-btn-hover-bg: #52585d;--bs-btn-hover-border-color: #484e53;--bs-btn-focus-shadow-rgb: 75, 80, 85;--bs-btn-active-color: #fff;--bs-btn-active-bg: #5d6166;--bs-btn-active-border-color: #484e53;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #343a40;--bs-btn-disabled-border-color: #343a40}nav.quarto-secondary-nav.color-navbar{background-color:#2780e3;color:#fdfeff}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#fdfeff}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:1em}body.nav-sidebar #title-block-header{margin-block-end:0}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}.code-annotated .code-copy-button{margin-right:1.25em;margin-top:0;padding-bottom:0;padding-top:3px}.code-annotation-gutter-bg{background-color:#fff}.code-annotation-gutter{background-color:rgba(233,236,239,.65)}.code-annotation-gutter,.code-annotation-gutter-bg{height:100%;width:calc(20px + .5em);position:absolute;top:0;right:0}dl.code-annotation-container-grid dt{margin-right:1em;margin-top:.25rem}dl.code-annotation-container-grid dt{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:#4b545c;border:solid #4b545c 1px;border-radius:50%;height:22px;width:22px;line-height:22px;font-size:11px;text-align:center;vertical-align:middle;text-decoration:none}dl.code-annotation-container-grid dt[data-target-cell]{cursor:pointer}dl.code-annotation-container-grid dt[data-target-cell].code-annotation-active{color:#fff;border:solid #aaa 1px;background-color:#aaa}pre.code-annotation-code{padding-top:0;padding-bottom:0}pre.code-annotation-code code{z-index:3}#code-annotation-line-highlight-gutter{width:100%;border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}#code-annotation-line-highlight{margin-left:-4em;width:calc(100% + 4em);border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}code.sourceCode .code-annotation-anchor.code-annotation-active{background-color:var(--quarto-hl-normal-color, #aaaaaa);border:solid var(--quarto-hl-normal-color, #aaaaaa) 1px;color:#e9ecef;font-weight:bolder}code.sourceCode .code-annotation-anchor{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;color:var(--quarto-hl-co-color);border:solid var(--quarto-hl-co-color) 1px;border-radius:50%;height:18px;width:18px;font-size:9px;margin-top:2px}code.sourceCode button.code-annotation-anchor{padding:2px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none}code.sourceCode a.code-annotation-anchor{line-height:18px;text-align:center;vertical-align:middle;cursor:default;text-decoration:none}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;opacity:.999}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;opacity:.999}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;opacity:.999}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#f8f9fa;z-index:998;opacity:.999;margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table{border-top:1px solid #ebedee;border-bottom:1px solid #ebedee}.table>thead{border-top-width:0;border-bottom:1px solid #b2bac1}.table a{word-break:break-word}.table>:not(caption)>*>*{background-color:unset;color:unset}#quarto-document-content .crosstalk-input .checkbox input[type=checkbox],#quarto-document-content .crosstalk-input .checkbox-inline input[type=checkbox]{position:unset;margin-top:unset;margin-left:unset}#quarto-document-content .row{margin-left:unset;margin-right:unset}.quarto-xref{white-space:nowrap}#quarto-draft-alert{margin-top:0px;margin-bottom:0px;padding:.3em;text-align:center;font-size:.9em}#quarto-draft-alert i{margin-right:.3em}a.external:after{content:"";background-image:url('data:image/svg+xml,');background-size:contain;background-repeat:no-repeat;background-position:center center;margin-left:.2em;padding-right:.75em}div.sourceCode code a.external:after{content:none}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#fdfeff;background:#2780e3}.quarto-title-banner a{color:#fdfeff}.quarto-title-banner h1,.quarto-title-banner .h1,.quarto-title-banner h2,.quarto-title-banner .h2{color:#fdfeff}.quarto-title-banner .code-tools-button{color:#97cbff}.quarto-title-banner .code-tools-button:hover{color:#fdfeff}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}@media(max-width: 767.98px){body.hypothesis-enabled #title-block-header>*{padding-right:20px}}main.quarto-banner-title-block>section:first-child>h2,main.quarto-banner-title-block>section:first-child>.h2,main.quarto-banner-title-block>section:first-child>h3,main.quarto-banner-title-block>section:first-child>.h3,main.quarto-banner-title-block>section:first-child>h4,main.quarto-banner-title-block>section:first-child>.h4{margin-top:0}.quarto-title .quarto-categories{display:flex;flex-wrap:wrap;row-gap:.5em;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.25rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}.quarto-title-meta-container{display:grid;grid-template-columns:1fr auto}.quarto-title-meta-column-end{display:flex;flex-direction:column;padding-left:1em}.quarto-title-meta-column-end a .bi{margin-right:.3em}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr);grid-column-gap:1em}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-0.2em;height:.8em;width:.8em}#title-block-header.quarto-title-block.default .quarto-title-author-email{opacity:.7}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.1em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .keywords,#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .keywords>p,#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .keywords>p:last-of-type,#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .keywords .block-title,#title-block-header.quarto-title-block.default .description .block-title,#title-block-header.quarto-title-block.default .abstract .block-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:minmax(max-content, 1fr) 1fr;grid-column-gap:1em}.quarto-title-tools-only{display:flex;justify-content:right}body{-webkit-font-smoothing:antialiased}.badge.bg-light{color:#343a40}.progress .progress-bar{font-size:8px;line-height:8px} diff --git a/site_libs/bootstrap/bootstrap.min.js b/site_libs/bootstrap/bootstrap.min.js new file mode 100644 index 00000000..e8f21f70 --- /dev/null +++ b/site_libs/bootstrap/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.3.1 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"

"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/site_libs/clipboard/clipboard.min.js b/site_libs/clipboard/clipboard.min.js new file mode 100644 index 00000000..1103f811 --- /dev/null +++ b/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); +// @license-end \ No newline at end of file diff --git a/site_libs/quarto-html/popper.min.js b/site_libs/quarto-html/popper.min.js new file mode 100644 index 00000000..e3726d72 --- /dev/null +++ b/site_libs/quarto-html/popper.min.js @@ -0,0 +1,6 @@ +/** + * @popperjs/core v2.11.7 - MIT License + */ + +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/site_libs/quarto-html/quarto-syntax-highlighting.css b/site_libs/quarto-html/quarto-syntax-highlighting.css new file mode 100644 index 00000000..b30ce576 --- /dev/null +++ b/site_libs/quarto-html/quarto-syntax-highlighting.css @@ -0,0 +1,205 @@ +/* quarto syntax highlight colors */ +:root { + --quarto-hl-ot-color: #003B4F; + --quarto-hl-at-color: #657422; + --quarto-hl-ss-color: #20794D; + --quarto-hl-an-color: #5E5E5E; + --quarto-hl-fu-color: #4758AB; + --quarto-hl-st-color: #20794D; + --quarto-hl-cf-color: #003B4F; + --quarto-hl-op-color: #5E5E5E; + --quarto-hl-er-color: #AD0000; + --quarto-hl-bn-color: #AD0000; + --quarto-hl-al-color: #AD0000; + --quarto-hl-va-color: #111111; + --quarto-hl-bu-color: inherit; + --quarto-hl-ex-color: inherit; + --quarto-hl-pp-color: #AD0000; + --quarto-hl-in-color: #5E5E5E; + --quarto-hl-vs-color: #20794D; + --quarto-hl-wa-color: #5E5E5E; + --quarto-hl-do-color: #5E5E5E; + --quarto-hl-im-color: #00769E; + --quarto-hl-ch-color: #20794D; + --quarto-hl-dt-color: #AD0000; + --quarto-hl-fl-color: #AD0000; + --quarto-hl-co-color: #5E5E5E; + --quarto-hl-cv-color: #5E5E5E; + --quarto-hl-cn-color: #8f5902; + --quarto-hl-sc-color: #5E5E5E; + --quarto-hl-dv-color: #AD0000; + --quarto-hl-kw-color: #003B4F; +} + +/* other quarto variables */ +:root { + --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +pre > code.sourceCode > span { + color: #003B4F; +} + +code span { + color: #003B4F; +} + +code.sourceCode > span { + color: #003B4F; +} + +div.sourceCode, +div.sourceCode pre.sourceCode { + color: #003B4F; +} + +code span.ot { + color: #003B4F; + font-style: inherit; +} + +code span.at { + color: #657422; + font-style: inherit; +} + +code span.ss { + color: #20794D; + font-style: inherit; +} + +code span.an { + color: #5E5E5E; + font-style: inherit; +} + +code span.fu { + color: #4758AB; + font-style: inherit; +} + +code span.st { + color: #20794D; + font-style: inherit; +} + +code span.cf { + color: #003B4F; + font-weight: bold; + font-style: inherit; +} + +code span.op { + color: #5E5E5E; + font-style: inherit; +} + +code span.er { + color: #AD0000; + font-style: inherit; +} + +code span.bn { + color: #AD0000; + font-style: inherit; +} + +code span.al { + color: #AD0000; + font-style: inherit; +} + +code span.va { + color: #111111; + font-style: inherit; +} + +code span.bu { + font-style: inherit; +} + +code span.ex { + font-style: inherit; +} + +code span.pp { + color: #AD0000; + font-style: inherit; +} + +code span.in { + color: #5E5E5E; + font-style: inherit; +} + +code span.vs { + color: #20794D; + font-style: inherit; +} + +code span.wa { + color: #5E5E5E; + font-style: italic; +} + +code span.do { + color: #5E5E5E; + font-style: italic; +} + +code span.im { + color: #00769E; + font-style: inherit; +} + +code span.ch { + color: #20794D; + font-style: inherit; +} + +code span.dt { + color: #AD0000; + font-style: inherit; +} + +code span.fl { + color: #AD0000; + font-style: inherit; +} + +code span.co { + color: #5E5E5E; + font-style: inherit; +} + +code span.cv { + color: #5E5E5E; + font-style: italic; +} + +code span.cn { + color: #8f5902; + font-style: inherit; +} + +code span.sc { + color: #5E5E5E; + font-style: inherit; +} + +code span.dv { + color: #AD0000; + font-style: inherit; +} + +code span.kw { + color: #003B4F; + font-weight: bold; + font-style: inherit; +} + +.prevent-inlining { + content: " { + // Find any conflicting margin elements and add margins to the + // top to prevent overlap + const marginChildren = window.document.querySelectorAll( + ".column-margin.column-container > *, .margin-caption, .aside" + ); + + let lastBottom = 0; + for (const marginChild of marginChildren) { + if (marginChild.offsetParent !== null) { + // clear the top margin so we recompute it + marginChild.style.marginTop = null; + const top = marginChild.getBoundingClientRect().top + window.scrollY; + if (top < lastBottom) { + const marginChildStyle = window.getComputedStyle(marginChild); + const marginBottom = parseFloat(marginChildStyle["marginBottom"]); + const margin = lastBottom - top + marginBottom; + marginChild.style.marginTop = `${margin}px`; + } + const styles = window.getComputedStyle(marginChild); + const marginTop = parseFloat(styles["marginTop"]); + lastBottom = top + marginChild.getBoundingClientRect().height + marginTop; + } + } +}; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Recompute the position of margin elements anytime the body size changes + if (window.ResizeObserver) { + const resizeObserver = new window.ResizeObserver( + throttle(() => { + layoutMarginEls(); + if ( + window.document.body.getBoundingClientRect().width < 990 && + isReaderMode() + ) { + quartoToggleReader(); + } + }, 50) + ); + resizeObserver.observe(window.document.body); + } + + const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]'); + const sidebarEl = window.document.getElementById("quarto-sidebar"); + const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left"); + const marginSidebarEl = window.document.getElementById( + "quarto-margin-sidebar" + ); + // function to determine whether the element has a previous sibling that is active + const prevSiblingIsActiveLink = (el) => { + const sibling = el.previousElementSibling; + if (sibling && sibling.tagName === "A") { + return sibling.classList.contains("active"); + } else { + return false; + } + }; + + // fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior) + function fireSlideEnter(e) { + const event = window.document.createEvent("Event"); + event.initEvent("slideenter", true, true); + window.document.dispatchEvent(event); + } + const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]'); + tabs.forEach((tab) => { + tab.addEventListener("shown.bs.tab", fireSlideEnter); + }); + + // fire slideEnter for tabby tab activations (for htmlwidget resize behavior) + document.addEventListener("tabby", fireSlideEnter, false); + + // Track scrolling and mark TOC links as active + // get table of contents and sidebar (bail if we don't have at least one) + const tocLinks = tocEl + ? [...tocEl.querySelectorAll("a[data-scroll-target]")] + : []; + const makeActive = (link) => tocLinks[link].classList.add("active"); + const removeActive = (link) => tocLinks[link].classList.remove("active"); + const removeAllActive = () => + [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link)); + + // activate the anchor for a section associated with this TOC entry + tocLinks.forEach((link) => { + link.addEventListener("click", () => { + if (link.href.indexOf("#") !== -1) { + const anchor = link.href.split("#")[1]; + const heading = window.document.querySelector( + `[data-anchor-id="${anchor}"]` + ); + if (heading) { + // Add the class + heading.classList.add("reveal-anchorjs-link"); + + // function to show the anchor + const handleMouseout = () => { + heading.classList.remove("reveal-anchorjs-link"); + heading.removeEventListener("mouseout", handleMouseout); + }; + + // add a function to clear the anchor when the user mouses out of it + heading.addEventListener("mouseout", handleMouseout); + } + } + }); + }); + + const sections = tocLinks.map((link) => { + const target = link.getAttribute("data-scroll-target"); + if (target.startsWith("#")) { + return window.document.getElementById(decodeURI(`${target.slice(1)}`)); + } else { + return window.document.querySelector(decodeURI(`${target}`)); + } + }); + + const sectionMargin = 200; + let currentActive = 0; + // track whether we've initialized state the first time + let init = false; + + const updateActiveLink = () => { + // The index from bottom to top (e.g. reversed list) + let sectionIndex = -1; + if ( + window.innerHeight + window.pageYOffset >= + window.document.body.offsetHeight + ) { + // This is the no-scroll case where last section should be the active one + sectionIndex = 0; + } else { + // This finds the last section visible on screen that should be made active + sectionIndex = [...sections].reverse().findIndex((section) => { + if (section) { + return window.pageYOffset >= section.offsetTop - sectionMargin; + } else { + return false; + } + }); + } + if (sectionIndex > -1) { + const current = sections.length - sectionIndex - 1; + if (current !== currentActive) { + removeAllActive(); + currentActive = current; + makeActive(current); + if (init) { + window.dispatchEvent(sectionChanged); + } + init = true; + } + } + }; + + const inHiddenRegion = (top, bottom, hiddenRegions) => { + for (const region of hiddenRegions) { + if (top <= region.bottom && bottom >= region.top) { + return true; + } + } + return false; + }; + + const categorySelector = "header.quarto-title-block .quarto-category"; + const activateCategories = (href) => { + // Find any categories + // Surround them with a link pointing back to: + // #category=Authoring + try { + const categoryEls = window.document.querySelectorAll(categorySelector); + for (const categoryEl of categoryEls) { + const categoryText = categoryEl.textContent; + if (categoryText) { + const link = `${href}#category=${encodeURIComponent(categoryText)}`; + const linkEl = window.document.createElement("a"); + linkEl.setAttribute("href", link); + for (const child of categoryEl.childNodes) { + linkEl.append(child); + } + categoryEl.appendChild(linkEl); + } + } + } catch { + // Ignore errors + } + }; + function hasTitleCategories() { + return window.document.querySelector(categorySelector) !== null; + } + + function offsetRelativeUrl(url) { + const offset = getMeta("quarto:offset"); + return offset ? offset + url : url; + } + + function offsetAbsoluteUrl(url) { + const offset = getMeta("quarto:offset"); + const baseUrl = new URL(offset, window.location); + + const projRelativeUrl = url.replace(baseUrl, ""); + if (projRelativeUrl.startsWith("/")) { + return projRelativeUrl; + } else { + return "/" + projRelativeUrl; + } + } + + // read a meta tag value + function getMeta(metaName) { + const metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; + } + + async function findAndActivateCategories() { + const currentPagePath = offsetAbsoluteUrl(window.location.href); + const response = await fetch(offsetRelativeUrl("listings.json")); + if (response.status == 200) { + return response.json().then(function (listingPaths) { + const listingHrefs = []; + for (const listingPath of listingPaths) { + const pathWithoutLeadingSlash = listingPath.listing.substring(1); + for (const item of listingPath.items) { + if ( + item === currentPagePath || + item === currentPagePath + "index.html" + ) { + // Resolve this path against the offset to be sure + // we already are using the correct path to the listing + // (this adjusts the listing urls to be rooted against + // whatever root the page is actually running against) + const relative = offsetRelativeUrl(pathWithoutLeadingSlash); + const baseUrl = window.location; + const resolvedPath = new URL(relative, baseUrl); + listingHrefs.push(resolvedPath.pathname); + break; + } + } + } + + // Look up the tree for a nearby linting and use that if we find one + const nearestListing = findNearestParentListing( + offsetAbsoluteUrl(window.location.pathname), + listingHrefs + ); + if (nearestListing) { + activateCategories(nearestListing); + } else { + // See if the referrer is a listing page for this item + const referredRelativePath = offsetAbsoluteUrl(document.referrer); + const referrerListing = listingHrefs.find((listingHref) => { + const isListingReferrer = + listingHref === referredRelativePath || + listingHref === referredRelativePath + "index.html"; + return isListingReferrer; + }); + + if (referrerListing) { + // Try to use the referrer if possible + activateCategories(referrerListing); + } else if (listingHrefs.length > 0) { + // Otherwise, just fall back to the first listing + activateCategories(listingHrefs[0]); + } + } + }); + } + } + if (hasTitleCategories()) { + findAndActivateCategories(); + } + + const findNearestParentListing = (href, listingHrefs) => { + if (!href || !listingHrefs) { + return undefined; + } + // Look up the tree for a nearby linting and use that if we find one + const relativeParts = href.substring(1).split("/"); + while (relativeParts.length > 0) { + const path = relativeParts.join("/"); + for (const listingHref of listingHrefs) { + if (listingHref.startsWith(path)) { + return listingHref; + } + } + relativeParts.pop(); + } + + return undefined; + }; + + const manageSidebarVisiblity = (el, placeholderDescriptor) => { + let isVisible = true; + let elRect; + + return (hiddenRegions) => { + if (el === null) { + return; + } + + // Find the last element of the TOC + const lastChildEl = el.lastElementChild; + + if (lastChildEl) { + // Converts the sidebar to a menu + const convertToMenu = () => { + for (const child of el.children) { + child.style.opacity = 0; + child.style.overflow = "hidden"; + child.style.pointerEvents = "none"; + } + + nexttick(() => { + const toggleContainer = window.document.createElement("div"); + toggleContainer.style.width = "100%"; + toggleContainer.classList.add("zindex-over-content"); + toggleContainer.classList.add("quarto-sidebar-toggle"); + toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom + toggleContainer.id = placeholderDescriptor.id; + toggleContainer.style.position = "fixed"; + + const toggleIcon = window.document.createElement("i"); + toggleIcon.classList.add("quarto-sidebar-toggle-icon"); + toggleIcon.classList.add("bi"); + toggleIcon.classList.add("bi-caret-down-fill"); + + const toggleTitle = window.document.createElement("div"); + const titleEl = window.document.body.querySelector( + placeholderDescriptor.titleSelector + ); + if (titleEl) { + toggleTitle.append( + titleEl.textContent || titleEl.innerText, + toggleIcon + ); + } + toggleTitle.classList.add("zindex-over-content"); + toggleTitle.classList.add("quarto-sidebar-toggle-title"); + toggleContainer.append(toggleTitle); + + const toggleContents = window.document.createElement("div"); + toggleContents.classList = el.classList; + toggleContents.classList.add("zindex-over-content"); + toggleContents.classList.add("quarto-sidebar-toggle-contents"); + for (const child of el.children) { + if (child.id === "toc-title") { + continue; + } + + const clone = child.cloneNode(true); + clone.style.opacity = 1; + clone.style.pointerEvents = null; + clone.style.display = null; + toggleContents.append(clone); + } + toggleContents.style.height = "0px"; + const positionToggle = () => { + // position the element (top left of parent, same width as parent) + if (!elRect) { + elRect = el.getBoundingClientRect(); + } + toggleContainer.style.left = `${elRect.left}px`; + toggleContainer.style.top = `${elRect.top}px`; + toggleContainer.style.width = `${elRect.width}px`; + }; + positionToggle(); + + toggleContainer.append(toggleContents); + el.parentElement.prepend(toggleContainer); + + // Process clicks + let tocShowing = false; + // Allow the caller to control whether this is dismissed + // when it is clicked (e.g. sidebar navigation supports + // opening and closing the nav tree, so don't dismiss on click) + const clickEl = placeholderDescriptor.dismissOnClick + ? toggleContainer + : toggleTitle; + + const closeToggle = () => { + if (tocShowing) { + toggleContainer.classList.remove("expanded"); + toggleContents.style.height = "0px"; + tocShowing = false; + } + }; + + // Get rid of any expanded toggle if the user scrolls + window.document.addEventListener( + "scroll", + throttle(() => { + closeToggle(); + }, 50) + ); + + // Handle positioning of the toggle + window.addEventListener( + "resize", + throttle(() => { + elRect = undefined; + positionToggle(); + }, 50) + ); + + window.addEventListener("quarto-hrChanged", () => { + elRect = undefined; + }); + + // Process the click + clickEl.onclick = () => { + if (!tocShowing) { + toggleContainer.classList.add("expanded"); + toggleContents.style.height = null; + tocShowing = true; + } else { + closeToggle(); + } + }; + }); + }; + + // Converts a sidebar from a menu back to a sidebar + const convertToSidebar = () => { + for (const child of el.children) { + child.style.opacity = 1; + child.style.overflow = null; + child.style.pointerEvents = null; + } + + const placeholderEl = window.document.getElementById( + placeholderDescriptor.id + ); + if (placeholderEl) { + placeholderEl.remove(); + } + + el.classList.remove("rollup"); + }; + + if (isReaderMode()) { + convertToMenu(); + isVisible = false; + } else { + // Find the top and bottom o the element that is being managed + const elTop = el.offsetTop; + const elBottom = + elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight; + + if (!isVisible) { + // If the element is current not visible reveal if there are + // no conflicts with overlay regions + if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToSidebar(); + isVisible = true; + } + } else { + // If the element is visible, hide it if it conflicts with overlay regions + // and insert a placeholder toggle (or if we're in reader mode) + if (inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToMenu(); + isVisible = false; + } + } + } + } + }; + }; + + const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]'); + for (const tabEl of tabEls) { + const id = tabEl.getAttribute("data-bs-target"); + if (id) { + const columnEl = document.querySelector( + `${id} .column-margin, .tabset-margin-content` + ); + if (columnEl) + tabEl.addEventListener("shown.bs.tab", function (event) { + const el = event.srcElement; + if (el) { + const visibleCls = `${el.id}-margin-content`; + // walk up until we find a parent tabset + let panelTabsetEl = el.parentElement; + while (panelTabsetEl) { + if (panelTabsetEl.classList.contains("panel-tabset")) { + break; + } + panelTabsetEl = panelTabsetEl.parentElement; + } + + if (panelTabsetEl) { + const prevSib = panelTabsetEl.previousElementSibling; + if ( + prevSib && + prevSib.classList.contains("tabset-margin-container") + ) { + const childNodes = prevSib.querySelectorAll( + ".tabset-margin-content" + ); + for (const childEl of childNodes) { + if (childEl.classList.contains(visibleCls)) { + childEl.classList.remove("collapse"); + } else { + childEl.classList.add("collapse"); + } + } + } + } + } + + layoutMarginEls(); + }); + } + } + + // Manage the visibility of the toc and the sidebar + const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, { + id: "quarto-toc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, { + id: "quarto-sidebarnav-toggle", + titleSelector: ".title", + dismissOnClick: false, + }); + let tocLeftScrollVisibility; + if (leftTocEl) { + tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, { + id: "quarto-lefttoc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + } + + // Find the first element that uses formatting in special columns + const conflictingEls = window.document.body.querySelectorAll( + '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]' + ); + + // Filter all the possibly conflicting elements into ones + // the do conflict on the left or ride side + const arrConflictingEls = Array.from(conflictingEls); + const leftSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return false; + } + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + className.startsWith("column-") && + !className.endsWith("right") && + !className.endsWith("container") && + className !== "column-margin" + ); + }); + }); + const rightSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return true; + } + + const hasMarginCaption = Array.from(el.classList).find((className) => { + return className == "margin-caption"; + }); + if (hasMarginCaption) { + return true; + } + + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + !className.endsWith("container") && + className.startsWith("column-") && + !className.endsWith("left") + ); + }); + }); + + const kOverlapPaddingSize = 10; + function toRegions(els) { + return els.map((el) => { + const boundRect = el.getBoundingClientRect(); + const top = + boundRect.top + + document.documentElement.scrollTop - + kOverlapPaddingSize; + return { + top, + bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize, + }; + }); + } + + let hasObserved = false; + const visibleItemObserver = (els) => { + let visibleElements = [...els]; + const intersectionObserver = new IntersectionObserver( + (entries, _observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + if (visibleElements.indexOf(entry.target) === -1) { + visibleElements.push(entry.target); + } + } else { + visibleElements = visibleElements.filter((visibleEntry) => { + return visibleEntry !== entry; + }); + } + }); + + if (!hasObserved) { + hideOverlappedSidebars(); + } + hasObserved = true; + }, + {} + ); + els.forEach((el) => { + intersectionObserver.observe(el); + }); + + return { + getVisibleEntries: () => { + return visibleElements; + }, + }; + }; + + const rightElementObserver = visibleItemObserver(rightSideConflictEls); + const leftElementObserver = visibleItemObserver(leftSideConflictEls); + + const hideOverlappedSidebars = () => { + marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries())); + sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries())); + if (tocLeftScrollVisibility) { + tocLeftScrollVisibility( + toRegions(leftElementObserver.getVisibleEntries()) + ); + } + }; + + window.quartoToggleReader = () => { + // Applies a slow class (or removes it) + // to update the transition speed + const slowTransition = (slow) => { + const manageTransition = (id, slow) => { + const el = document.getElementById(id); + if (el) { + if (slow) { + el.classList.add("slow"); + } else { + el.classList.remove("slow"); + } + } + }; + + manageTransition("TOC", slow); + manageTransition("quarto-sidebar", slow); + }; + const readerMode = !isReaderMode(); + setReaderModeValue(readerMode); + + // If we're entering reader mode, slow the transition + if (readerMode) { + slowTransition(readerMode); + } + highlightReaderToggle(readerMode); + hideOverlappedSidebars(); + + // If we're exiting reader mode, restore the non-slow transition + if (!readerMode) { + slowTransition(!readerMode); + } + }; + + const highlightReaderToggle = (readerMode) => { + const els = document.querySelectorAll(".quarto-reader-toggle"); + if (els) { + els.forEach((el) => { + if (readerMode) { + el.classList.add("reader"); + } else { + el.classList.remove("reader"); + } + }); + } + }; + + const setReaderModeValue = (val) => { + if (window.location.protocol !== "file:") { + window.localStorage.setItem("quarto-reader-mode", val); + } else { + localReaderMode = val; + } + }; + + const isReaderMode = () => { + if (window.location.protocol !== "file:") { + return window.localStorage.getItem("quarto-reader-mode") === "true"; + } else { + return localReaderMode; + } + }; + let localReaderMode = null; + + const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded"); + const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1; + + // Walk the TOC and collapse/expand nodes + // Nodes are expanded if: + // - they are top level + // - they have children that are 'active' links + // - they are directly below an link that is 'active' + const walk = (el, depth) => { + // Tick depth when we enter a UL + if (el.tagName === "UL") { + depth = depth + 1; + } + + // It this is active link + let isActiveNode = false; + if (el.tagName === "A" && el.classList.contains("active")) { + isActiveNode = true; + } + + // See if there is an active child to this element + let hasActiveChild = false; + for (child of el.children) { + hasActiveChild = walk(child, depth) || hasActiveChild; + } + + // Process the collapse state if this is an UL + if (el.tagName === "UL") { + if (tocOpenDepth === -1 && depth > 1) { + // toc-expand: false + el.classList.add("collapse"); + } else if ( + depth <= tocOpenDepth || + hasActiveChild || + prevSiblingIsActiveLink(el) + ) { + el.classList.remove("collapse"); + } else { + el.classList.add("collapse"); + } + + // untick depth when we leave a UL + depth = depth - 1; + } + return hasActiveChild || isActiveNode; + }; + + // walk the TOC and expand / collapse any items that should be shown + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + + // Throttle the scroll event and walk peridiocally + window.document.addEventListener( + "scroll", + throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 5) + ); + window.addEventListener( + "resize", + throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 10) + ); + hideOverlappedSidebars(); + highlightReaderToggle(isReaderMode()); +}); + +// grouped tabsets +window.addEventListener("pageshow", (_event) => { + function getTabSettings() { + const data = localStorage.getItem("quarto-persistent-tabsets-data"); + if (!data) { + localStorage.setItem("quarto-persistent-tabsets-data", "{}"); + return {}; + } + if (data) { + return JSON.parse(data); + } + } + + function setTabSettings(data) { + localStorage.setItem( + "quarto-persistent-tabsets-data", + JSON.stringify(data) + ); + } + + function setTabState(groupName, groupValue) { + const data = getTabSettings(); + data[groupName] = groupValue; + setTabSettings(data); + } + + function toggleTab(tab, active) { + const tabPanelId = tab.getAttribute("aria-controls"); + const tabPanel = document.getElementById(tabPanelId); + if (active) { + tab.classList.add("active"); + tabPanel.classList.add("active"); + } else { + tab.classList.remove("active"); + tabPanel.classList.remove("active"); + } + } + + function toggleAll(selectedGroup, selectorsToSync) { + for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) { + const active = selectedGroup === thisGroup; + for (const tab of tabs) { + toggleTab(tab, active); + } + } + } + + function findSelectorsToSyncByLanguage() { + const result = {}; + const tabs = Array.from( + document.querySelectorAll(`div[data-group] a[id^='tabset-']`) + ); + for (const item of tabs) { + const div = item.parentElement.parentElement.parentElement; + const group = div.getAttribute("data-group"); + if (!result[group]) { + result[group] = {}; + } + const selectorsToSync = result[group]; + const value = item.innerHTML; + if (!selectorsToSync[value]) { + selectorsToSync[value] = []; + } + selectorsToSync[value].push(item); + } + return result; + } + + function setupSelectorSync() { + const selectorsToSync = findSelectorsToSyncByLanguage(); + Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => { + Object.entries(tabSetsByValue).forEach(([value, items]) => { + items.forEach((item) => { + item.addEventListener("click", (_event) => { + setTabState(group, value); + toggleAll(value, selectorsToSync[group]); + }); + }); + }); + }); + return selectorsToSync; + } + + const selectorsToSync = setupSelectorSync(); + for (const [group, selectedName] of Object.entries(getTabSettings())) { + const selectors = selectorsToSync[group]; + // it's possible that stale state gives us empty selections, so we explicitly check here. + if (selectors) { + toggleAll(selectedName, selectors); + } + } +}); + +function throttle(func, wait) { + let waiting = false; + return function () { + if (!waiting) { + func.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, wait); + } + }; +} + +function nexttick(func) { + return setTimeout(func, 0); +} diff --git a/site_libs/quarto-html/tippy.css b/site_libs/quarto-html/tippy.css new file mode 100644 index 00000000..e6ae635c --- /dev/null +++ b/site_libs/quarto-html/tippy.css @@ -0,0 +1 @@ +.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} \ No newline at end of file diff --git a/site_libs/quarto-html/tippy.umd.min.js b/site_libs/quarto-html/tippy.umd.min.js new file mode 100644 index 00000000..ca292be3 --- /dev/null +++ b/site_libs/quarto-html/tippy.umd.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow='',F})); + diff --git a/site_libs/quarto-nav/headroom.min.js b/site_libs/quarto-nav/headroom.min.js new file mode 100644 index 00000000..b08f1dff --- /dev/null +++ b/site_libs/quarto-nav/headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); diff --git a/site_libs/quarto-nav/quarto-nav.js b/site_libs/quarto-nav/quarto-nav.js new file mode 100644 index 00000000..38cc4305 --- /dev/null +++ b/site_libs/quarto-nav/quarto-nav.js @@ -0,0 +1,325 @@ +const headroomChanged = new CustomEvent("quarto-hrChanged", { + detail: {}, + bubbles: true, + cancelable: false, + composed: false, +}); + +const announceDismiss = () => { + const annEl = window.document.getElementById("quarto-announcement"); + if (annEl) { + annEl.remove(); + + const annId = annEl.getAttribute("data-announcement-id"); + window.localStorage.setItem(`quarto-announce-${annId}`, "true"); + } +}; + +const announceRegister = () => { + const annEl = window.document.getElementById("quarto-announcement"); + if (annEl) { + const annId = annEl.getAttribute("data-announcement-id"); + const isDismissed = + window.localStorage.getItem(`quarto-announce-${annId}`) || false; + if (isDismissed) { + announceDismiss(); + return; + } else { + annEl.classList.remove("hidden"); + } + + const actionEl = annEl.querySelector(".quarto-announcement-action"); + if (actionEl) { + actionEl.addEventListener("click", function (e) { + e.preventDefault(); + // Hide the bar immediately + announceDismiss(); + }); + } + } +}; + +window.document.addEventListener("DOMContentLoaded", function () { + let init = false; + + announceRegister(); + + // Manage the back to top button, if one is present. + let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollDownBuffer = 5; + const scrollUpBuffer = 35; + const btn = document.getElementById("quarto-back-to-top"); + const hideBackToTop = () => { + btn.style.display = "none"; + }; + const showBackToTop = () => { + btn.style.display = "inline-block"; + }; + if (btn) { + window.document.addEventListener( + "scroll", + function () { + const currentScrollTop = + window.pageYOffset || document.documentElement.scrollTop; + + // Shows and hides the button 'intelligently' as the user scrolls + if (currentScrollTop - scrollDownBuffer > lastScrollTop) { + hideBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } else if (currentScrollTop < lastScrollTop - scrollUpBuffer) { + showBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } + + // Show the button at the bottom, hides it at the top + if (currentScrollTop <= 0) { + hideBackToTop(); + } else if ( + window.innerHeight + currentScrollTop >= + document.body.offsetHeight + ) { + showBackToTop(); + } + }, + false + ); + } + + function throttle(func, wait) { + var timeout; + return function () { + const context = this; + const args = arguments; + const later = function () { + clearTimeout(timeout); + timeout = null; + func.apply(context, args); + }; + + if (!timeout) { + timeout = setTimeout(later, wait); + } + }; + } + + function headerOffset() { + // Set an offset if there is are fixed top navbar + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl) { + return headerEl.clientHeight; + } else { + return 0; + } + } + + function footerOffset() { + const footerEl = window.document.querySelector("footer.footer"); + if (footerEl) { + return footerEl.clientHeight; + } else { + return 0; + } + } + + function dashboardOffset() { + const dashboardNavEl = window.document.getElementById( + "quarto-dashboard-header" + ); + if (dashboardNavEl !== null) { + return dashboardNavEl.clientHeight; + } else { + return 0; + } + } + + function updateDocumentOffsetWithoutAnimation() { + updateDocumentOffset(false); + } + + function updateDocumentOffset(animated) { + // set body offset + const topOffset = headerOffset(); + const bodyOffset = topOffset + footerOffset() + dashboardOffset(); + const bodyEl = window.document.body; + bodyEl.setAttribute("data-bs-offset", topOffset); + bodyEl.style.paddingTop = topOffset + "px"; + + // deal with sidebar offsets + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + if (!animated) { + sidebar.classList.add("notransition"); + // Remove the no transition class after the animation has time to complete + setTimeout(function () { + sidebar.classList.remove("notransition"); + }, 201); + } + + if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { + sidebar.style.top = "0"; + sidebar.style.maxHeight = "100vh"; + } else { + sidebar.style.top = topOffset + "px"; + sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; + } + }); + + // allow space for footer + const mainContainer = window.document.querySelector(".quarto-container"); + if (mainContainer) { + mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; + } + + // link offset + let linkStyle = window.document.querySelector("#quarto-target-style"); + if (!linkStyle) { + linkStyle = window.document.createElement("style"); + linkStyle.setAttribute("id", "quarto-target-style"); + window.document.head.appendChild(linkStyle); + } + while (linkStyle.firstChild) { + linkStyle.removeChild(linkStyle.firstChild); + } + if (topOffset > 0) { + linkStyle.appendChild( + window.document.createTextNode(` + section:target::before { + content: ""; + display: block; + height: ${topOffset}px; + margin: -${topOffset}px 0 0; + }`) + ); + } + if (init) { + window.dispatchEvent(headroomChanged); + } + init = true; + } + + // initialize headroom + var header = window.document.querySelector("#quarto-header"); + if (header && window.Headroom) { + const headroom = new window.Headroom(header, { + tolerance: 5, + onPin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.remove("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + onUnpin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.add("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + }); + headroom.init(); + + let frozen = false; + window.quartoToggleHeadroom = function () { + if (frozen) { + headroom.unfreeze(); + frozen = false; + } else { + headroom.freeze(); + frozen = true; + } + }; + } + + window.addEventListener( + "hashchange", + function (e) { + if ( + getComputedStyle(document.documentElement).scrollBehavior !== "smooth" + ) { + window.scrollTo(0, window.pageYOffset - headerOffset()); + } + }, + false + ); + + // Observe size changed for the header + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl && window.ResizeObserver) { + const observer = new window.ResizeObserver(() => { + setTimeout(updateDocumentOffsetWithoutAnimation, 0); + }); + observer.observe(headerEl, { + attributes: true, + childList: true, + characterData: true, + }); + } else { + window.addEventListener( + "resize", + throttle(updateDocumentOffsetWithoutAnimation, 50) + ); + } + setTimeout(updateDocumentOffsetWithoutAnimation, 250); + + // fixup index.html links if we aren't on the filesystem + if (window.location.protocol !== "file:") { + const links = window.document.querySelectorAll("a"); + for (let i = 0; i < links.length; i++) { + if (links[i].href) { + links[i].dataset.originalHref = links[i].href; + links[i].href = links[i].href.replace(/\/index\.html/, "/"); + } + } + + // Fixup any sharing links that require urls + // Append url to any sharing urls + const sharingLinks = window.document.querySelectorAll( + "a.sidebar-tools-main-item, a.quarto-navigation-tool, a.quarto-navbar-tools, a.quarto-navbar-tools-item" + ); + for (let i = 0; i < sharingLinks.length; i++) { + const sharingLink = sharingLinks[i]; + const href = sharingLink.getAttribute("href"); + if (href) { + sharingLink.setAttribute( + "href", + href.replace("|url|", window.location.href) + ); + } + } + + // Scroll the active navigation item into view, if necessary + const navSidebar = window.document.querySelector("nav#quarto-sidebar"); + if (navSidebar) { + // Find the active item + const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); + if (activeItem) { + // Wait for the scroll height and height to resolve by observing size changes on the + // nav element that is scrollable + const resizeObserver = new ResizeObserver((_entries) => { + // The bottom of the element + const elBottom = activeItem.offsetTop; + const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; + + // The element height and scroll height are the same, then we are still loading + if (viewBottom !== navSidebar.scrollHeight) { + // Determine if the item isn't visible and scroll to it + if (elBottom >= viewBottom) { + navSidebar.scrollTop = elBottom; + } + + // stop observing now since we've completed the scroll + resizeObserver.unobserve(navSidebar); + } + }); + resizeObserver.observe(navSidebar); + } + } + } +}); diff --git a/site_libs/quarto-search/autocomplete.umd.js b/site_libs/quarto-search/autocomplete.umd.js new file mode 100644 index 00000000..ae0063aa --- /dev/null +++ b/site_libs/quarto-search/autocomplete.umd.js @@ -0,0 +1,3 @@ +/*! @algolia/autocomplete-js 1.11.1 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@algolia/autocomplete-js"]={})}(this,(function(e){"use strict";function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(e){for(var n=1;n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);l=!0);}catch(e){c=!0,o=e}finally{try{if(!l&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(c)throw o}}return a}}(e,t)||c(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||c(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function N(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r=3||2===n&&r>=4||1===n&&r>=10);function i(t,n,r){if(o&&void 0!==r){var i=r[0].__autocomplete_algoliaCredentials,u={"X-Algolia-Application-Id":i.appId,"X-Algolia-API-Key":i.apiKey};e.apply(void 0,[t].concat(D(n),[{headers:u}]))}else e.apply(void 0,[t].concat(D(n)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("clickedObjectIDsAfterSearch",B(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("clickedObjectIDs",B(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("convertedObjectIDsAfterSearch",B(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&i("convertedObjectIDs",B(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n0&&t.reduce((function(e,t){var n=t.items,r=k(t,A);return[].concat(D(e),D(q(N(N({},r),{},{objectIDs:(null==n?void 0:n.map((function(e){return e.objectID})))||r.objectIDs})).map((function(e){return{items:n,payload:e}}))))}),[]).forEach((function(e){var t=e.items;return i("viewedObjectIDs",[e.payload],t)}))},viewedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function F(e){var t=e.items.reduce((function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function L(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function M(e){return function(e){if(Array.isArray(e))return H(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return H(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return H(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function H(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&z({onItemsChange:r,items:n,insights:a,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive;function l(e){t({algoliaInsightsPlugin:{__algoliaSearchParameters:W({clickAnalytics:!0},e?{userToken:e}:{}),insights:a}})}u("addAlgoliaAgent","insights-plugin"),l(),u("onUserTokenChange",l),u("getUserToken",null,(function(e,t){l(t)})),n((function(e){var t=e.item,n=e.state,r=e.event,i=e.source;L(t)&&o({state:n,event:r,insights:a,item:t,insightsEvents:[W({eventName:"Item Selected"},j({item:t,items:i.getItems().filter(L)}))]})})),r((function(e){var t=e.item,n=e.source,r=e.state,o=e.event;L(t)&&i({state:r,event:o,insights:a,item:t,insightsEvents:[W({eventName:"Item Active"},j({item:t,items:n.getItems().filter(L)}))]})}))},onStateChange:function(e){var t=e.state;c({state:t})},__autocomplete_pluginOptions:e}}function J(e,t){var n=t;return{then:function(t,r){return J(e.then(Y(t,n,e),Y(r,n,e)),n)},catch:function(t){return J(e.catch(Y(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),J(e.finally(Y(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function X(e){return J(e,{isCanceled:!1,onCancelList:[]})}function Y(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function Z(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function ee(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function te(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:d(),plugins:o,initialState:he({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(ye(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:O,onResolve:O};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=te(te({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return m(e)})).then((function(e){return e.map((function(e){return he(he({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:he({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function Se(e){return Se="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Se(e)}function je(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Pe(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var He,Ve,We,Ke=null,Qe=(He=-1,Ve=-1,We=void 0,function(e){var t=++He;return Promise.resolve(e).then((function(e){return We&&t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function et(e){return et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},et(e)}var tt=["props","refresh","store"],nt=["inputElement","formElement","panelElement"],rt=["inputElement"],ot=["inputElement","maxLength"],it=["source"],ut=["item","source"];function at(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function lt(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ft(e){var t=e.props,n=e.refresh,r=e.store,o=st(e,tt);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,i=e.panelElement;function u(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,i].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return lt({onTouchStart:u,onMouseDown:u,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},st(e,nt))},getRootProps:function(e){return lt({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return ie(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":ie(t.id,"label")},e)},getFormProps:function(e){return e.inputElement,lt({action:"",noValidate:!0,role:"search",onSubmit:function(i){var u;i.preventDefault(),t.onSubmit(lt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(u=e.inputElement)||void 0===u||u.blur()},onReset:function(i){var u;i.preventDefault(),t.onReset(lt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(u=e.inputElement)||void 0===u||u.focus()}},st(e,rt))},getLabelProps:function(e){return lt({htmlFor:ie(t.id,"input"),id:ie(t.id,"label")},e)},getInputProps:function(e){var i;function u(e){(t.openOnFocus||Boolean(r.getState().query))&&$e(lt({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var a=e||{};a.inputElement;var l=a.maxLength,c=void 0===l?512:l,s=st(a,ot),f=oe(r.getState()),p=function(e){return Boolean(e&&e.match(ue))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),m=t.enterKeyHint||(null!=f&&f.itemUrl&&!p?"go":"search");return lt({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?ie(t.id,"item-".concat(r.getState().activeItemId),null==f?void 0:f.source):void 0,"aria-controls":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return ie(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":ie(t.id,"label"),value:r.getState().completion||r.getState().query,id:ie(t.id,"input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:m,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:c,type:"search",onChange:function(e){$e(lt({event:e,props:t,query:e.currentTarget.value.slice(0,c),refresh:n,store:r},o))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=Ze(e,Ge);if("ArrowUp"===t.key||"ArrowDown"===t.key){var u=function(){var e=oe(o.getState()),t=n.environment.document.getElementById(ie(n.id,"item-".concat(o.getState().activeItemId),null==e?void 0:e.source));t&&(t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded(!1):t.scrollIntoView(!1))},a=function(){var e=oe(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,u=e.itemInputValue,a=e.itemUrl,l=e.source;l.onActive(Xe({event:t,item:n,itemInputValue:u,itemUrl:a,refresh:r,source:l,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?$e(Xe({event:t,props:n,query:o.getState().query,refresh:r,store:o},i)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),a(),setTimeout(u,0)})):(o.dispatch(t.key,{}),a(),u())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var l=oe(o.getState()),c=l.item,s=l.itemInputValue,f=l.itemUrl,p=l.source;if(t.metaKey||t.ctrlKey)void 0!==f&&(p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:f,item:c,state:o.getState()}));else if(t.shiftKey)void 0!==f&&(p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:f,item:c,state:o.getState()}));else if(t.altKey);else{if(void 0!==f)return p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),void n.navigator.navigate({itemUrl:f,item:c,state:o.getState()});$e(Xe({event:t,nextState:{isOpen:!1},props:n,query:s,refresh:r,store:o},i)).then((function(){p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i))}))}}}(lt({event:e,props:t,refresh:n,store:r},o))},onFocus:u,onBlur:O,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||u(n)}},s)},getPanelProps:function(e){return lt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.source,o=st(n,it);return lt({role:"listbox","aria-labelledby":ie(t.id,"label"),id:ie(t.id,"list",r)},o)},getItemProps:function(e){var i=e.item,u=e.source,a=st(e,ut);return lt({id:ie(t.id,"item-".concat(i.__autocomplete_id),u),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=oe(r.getState());if(null!==r.getState().activeItemId&&t){var u=t.item,a=t.itemInputValue,l=t.itemUrl,c=t.source;c.onActive(lt({event:e,item:u,itemInputValue:a,itemUrl:l,refresh:n,source:c,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=u.getItemInputValue({item:i,state:r.getState()}),l=u.getItemUrl({item:i,state:r.getState()});(l?Promise.resolve():$e(lt({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){u.onSelect(lt({event:e,item:i,itemInputValue:a,itemUrl:l,refresh:n,source:u,state:r.getState()},o))}))}},a)}}}function pt(e){return pt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},pt(e)}function mt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function vt(e){for(var t=1;t=5&&((o||!e&&5===r)&&(u.push(r,0,o,n),r=6),e&&(u.push(r,e,0,n),r=6)),o=""},l=0;l"===t?(r=1,o=""):o=t+o[0]:i?t===i?i="":o+=t:'"'===t||"'"===t?i=t:">"===t?(a(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[l][c+1])?(a(),3===r&&(u=u[0]),r=u,(u=u[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(a(),r=2):o+=t),3===r&&"!--"===o&&(r=4,u=u[0])}return a(),u}(e)),t),arguments,[])).length>1?t:t[0]}var kt=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n};function xt(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function Nt(){for(var e=arguments.length,t=new Array(e),n=0;n2&&(u.children=arguments.length>3?Jt.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===u[i]&&(u[i]=e.defaultProps[i]);return sn(e,u,r,o,null)}function sn(e,t,n,r,o){var i={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++Yt:o};return null==o&&null!=Xt.vnode&&Xt.vnode(i),i}function fn(e){return e.children}function pn(e,t){this.props=e,this.context=t}function mn(e,t){if(null==t)return e.__?mn(e.__,e.__.__k.indexOf(e)+1):null;for(var n;tt&&Zt.sort(nn));yn.__r=0}function bn(e,t,n,r,o,i,u,a,l,c){var s,f,p,m,v,d,y,b=r&&r.__k||on,g=b.length;for(n.__k=[],s=0;s0?sn(m.type,m.props,m.key,m.ref?m.ref:null,m.__v):m)){if(m.__=n,m.__b=n.__b+1,null===(p=b[s])||p&&m.key==p.key&&m.type===p.type)b[s]=void 0;else for(f=0;f=0;t--)if((n=e.__k[t])&&(r=On(n)))return r;return null}function _n(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||un.test(t)?n:n+"px"}function Sn(e,t,n,r,o){var i;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||_n(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||_n(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])i=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=n,n?r||e.addEventListener(t,i?Pn:jn,i):e.removeEventListener(t,i?Pn:jn,i);else if("dangerouslySetInnerHTML"!==t){if(o)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!==t[4]?e.removeAttribute(t):e.setAttribute(t,n))}}function jn(e){return this.l[e.type+!1](Xt.event?Xt.event(e):e)}function Pn(e){return this.l[e.type+!0](Xt.event?Xt.event(e):e)}function wn(e,t,n,r,o,i,u,a,l){var c,s,f,p,m,v,d,y,b,g,h,O,_,S,j,P=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(l=n.__h,a=t.__e=n.__e,t.__h=null,i=[a]),(c=Xt.__b)&&c(t);try{e:if("function"==typeof P){if(y=t.props,b=(c=P.contextType)&&r[c.__c],g=c?b?b.props.value:c.__:r,n.__c?d=(s=t.__c=n.__c).__=s.__E:("prototype"in P&&P.prototype.render?t.__c=s=new P(y,g):(t.__c=s=new pn(y,g),s.constructor=P,s.render=Cn),b&&b.sub(s),s.props=y,s.state||(s.state={}),s.context=g,s.__n=r,f=s.__d=!0,s.__h=[],s._sb=[]),null==s.__s&&(s.__s=s.state),null!=P.getDerivedStateFromProps&&(s.__s==s.state&&(s.__s=an({},s.__s)),an(s.__s,P.getDerivedStateFromProps(y,s.__s))),p=s.props,m=s.state,s.__v=t,f)null==P.getDerivedStateFromProps&&null!=s.componentWillMount&&s.componentWillMount(),null!=s.componentDidMount&&s.__h.push(s.componentDidMount);else{if(null==P.getDerivedStateFromProps&&y!==p&&null!=s.componentWillReceiveProps&&s.componentWillReceiveProps(y,g),!s.__e&&null!=s.shouldComponentUpdate&&!1===s.shouldComponentUpdate(y,s.__s,g)||t.__v===n.__v){for(t.__v!==n.__v&&(s.props=y,s.state=s.__s,s.__d=!1),s.__e=!1,t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),h=0;h0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(xn);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function Tn(e){return function(e){if(Array.isArray(e))return qn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return qn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return qn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function qn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n",""":'"',"'":"'"},Fn=new RegExp(/\w/i),Ln=/&(amp|quot|lt|gt|#39);/g,Un=RegExp(Ln.source);function Mn(e,t){var n,r,o,i=e[t],u=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,a=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return Fn.test((o=i.value)&&Un.test(o)?o.replace(Ln,(function(e){return Rn[e]})):o)||a!==u?i.isHighlighted:a}function Hn(e){return Hn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Hn(e)}function Vn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Wn(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ur(e){return function(e){if(Array.isArray(e))return ar(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ar(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ar(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ar(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;if(!O.value.core.openOnFocus&&!t.query)return n;var r=Boolean(y.current||O.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:br,options:e}}))})),j=f(n({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},O.value.core.initialState)),P={getEnvironmentProps:O.value.renderer.getEnvironmentProps,getFormProps:O.value.renderer.getFormProps,getInputProps:O.value.renderer.getInputProps,getItemProps:O.value.renderer.getItemProps,getLabelProps:O.value.renderer.getLabelProps,getListProps:O.value.renderer.getListProps,getPanelProps:O.value.renderer.getPanelProps,getRootProps:O.value.renderer.getRootProps},w={setActiveItemId:S.value.setActiveItemId,setQuery:S.value.setQuery,setCollections:S.value.setCollections,setIsOpen:S.value.setIsOpen,setStatus:S.value.setStatus,setContext:S.value.setContext,refresh:S.value.refresh,navigator:S.value.navigator},I=m((function(){return Ct.bind(O.value.renderer.renderer.createElement)})),A=m((function(){return Gt({autocomplete:S.value,autocompleteScopeApi:w,classNames:O.value.renderer.classNames,environment:O.value.core.environment,isDetached:_.value,placeholder:O.value.core.placeholder,propGetters:P,setIsModalOpen:k,state:j.current,translations:O.value.renderer.translations})}));function E(){Ht(A.value.panel,{style:_.value?{}:yr({panelPlacement:O.value.renderer.panelPlacement,container:A.value.root,form:A.value.form,environment:O.value.core.environment})})}function D(e){j.current=e;var t={autocomplete:S.value,autocompleteScopeApi:w,classNames:O.value.renderer.classNames,components:O.value.renderer.components,container:O.value.renderer.container,html:I.value,dom:A.value,panelContainer:_.value?A.value.detachedContainer:O.value.renderer.panelContainer,propGetters:P,state:j.current,renderer:O.value.renderer.renderer},r=!b(e)&&!y.current&&O.value.renderer.renderNoResults||O.value.renderer.render;!function(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.dom,i=e.propGetters,u=e.state;Vt(o.root,i.getRootProps(n({state:u,props:t.getRootProps({})},r))),Vt(o.input,i.getInputProps(n({state:u,props:t.getInputProps({inputElement:o.input}),inputElement:o.input},r))),Ht(o.label,{hidden:"stalled"===u.status}),Ht(o.loadingIndicator,{hidden:"stalled"!==u.status}),Ht(o.clearButton,{hidden:!u.query}),Ht(o.detachedSearchButtonQuery,{textContent:u.query}),Ht(o.detachedSearchButtonPlaceholder,{hidden:Boolean(u.query)})}(t),function(e,t){var r=t.autocomplete,o=t.autocompleteScopeApi,u=t.classNames,a=t.html,l=t.dom,c=t.panelContainer,s=t.propGetters,f=t.state,p=t.components,m=t.renderer;if(f.isOpen){c.contains(l.panel)||"loading"===f.status||c.appendChild(l.panel),l.panel.classList.toggle("aa-Panel--stalled","stalled"===f.status);var v=f.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var l=e.source,c=e.items;return m.createElement("section",{key:t,className:u.source,"data-autocomplete-source-id":l.sourceId},l.templates.header&&m.createElement("div",{className:u.sourceHeader},l.templates.header({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})),l.templates.noResults&&0===c.length?m.createElement("div",{className:u.sourceNoResults},l.templates.noResults({components:p,createElement:m.createElement,Fragment:m.Fragment,source:l,state:f,html:a})):m.createElement("ul",i({className:u.list},s.getListProps(n({state:f,props:r.getListProps({source:l})},o))),c.map((function(e){var t=r.getItemProps({item:e,source:l});return m.createElement("li",i({key:t.id,className:u.item},s.getItemProps(n({state:f,props:t},o))),l.templates.item({components:p,createElement:m.createElement,Fragment:m.Fragment,item:e,state:f,html:a}))}))),l.templates.footer&&m.createElement("div",{className:u.sourceFooter},l.templates.footer({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})))})),d=m.createElement(m.Fragment,null,m.createElement("div",{className:u.panelLayout},v),m.createElement("div",{className:"aa-GradientBottom"})),y=v.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(n(n({children:d,state:f,sections:v,elements:y},m),{},{components:p,html:a},o),l.panel)}else c.contains(l.panel)&&c.removeChild(l.panel)}(r,t)}function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};l();var t=O.value.renderer,n=t.components,r=u(t,gr);g.current=qt(r,O.value.core,{components:Bt(n,(function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")})),initialState:j.current},e),v(),c(),S.value.refresh().then((function(){D(j.current)}))}function k(e){requestAnimationFrame((function(){var t=O.value.core.environment.document.body.contains(A.value.detachedOverlay);e!==t&&(e?(O.value.core.environment.document.body.appendChild(A.value.detachedOverlay),O.value.core.environment.document.body.classList.add("aa-Detached"),A.value.input.focus()):(O.value.core.environment.document.body.removeChild(A.value.detachedOverlay),O.value.core.environment.document.body.classList.remove("aa-Detached")))}))}return a((function(){var e=S.value.getEnvironmentProps({formElement:A.value.form,panelElement:A.value.panel,inputElement:A.value.input});return Ht(O.value.core.environment,e),function(){Ht(O.value.core.environment,Object.keys(e).reduce((function(e,t){return n(n({},e),{},o({},t,void 0))}),{}))}})),a((function(){var e=_.value?O.value.core.environment.document.body:O.value.renderer.panelContainer,t=_.value?A.value.detachedOverlay:A.value.panel;return _.value&&j.current.isOpen&&k(!0),D(j.current),function(){e.contains(t)&&e.removeChild(t)}})),a((function(){var e=O.value.renderer.container;return e.appendChild(A.value.root),function(){e.removeChild(A.value.root)}})),a((function(){var e=p((function(e){D(e.state)}),0);return h.current=function(t){var n=t.state,r=t.prevState;(_.value&&r.isOpen!==n.isOpen&&k(n.isOpen),_.value||!n.isOpen||r.isOpen||E(),n.query!==r.query)&&O.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){h.current=void 0}})),a((function(){var e=p((function(){var e=_.value;_.value=O.value.core.environment.matchMedia(O.value.renderer.detachedMediaQuery).matches,e!==_.value?C({}):requestAnimationFrame(E)}),20);return O.value.core.environment.addEventListener("resize",e),function(){O.value.core.environment.removeEventListener("resize",e)}})),a((function(){if(!_.value)return function(){};function e(e){A.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=O.value.core.environment.matchMedia(getComputedStyle(O.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),a((function(){return requestAnimationFrame(E),function(){}})),n(n({},w),{},{update:C,destroy:function(){l()}})},e.getAlgoliaFacets=function(e){var t=hr({transformResponse:function(e){return e.facetHits}}),r=e.queries.map((function(e){return n(n({},e),{},{type:"facet"})}));return t(n(n({},e),{},{queries:r}))},e.getAlgoliaResults=Or,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/site_libs/quarto-search/fuse.min.js b/site_libs/quarto-search/fuse.min.js new file mode 100644 index 00000000..adc28356 --- /dev/null +++ b/site_libs/quarto-search/fuse.min.js @@ -0,0 +1,9 @@ +/** + * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2022 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(C).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}var $=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?I.getFn:n,o=t.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o;r(this,e),this.norm=E(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,g(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();g(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?I.getFn:r,o=n.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o,a=new $({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(_)),a.setSources(t),a.create(),a}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?I.distance:s,h=t.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}function N(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}var P=32;function W(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?I.location:o,a=i.threshold,s=void 0===a?I.threshold:a,u=i.distance,h=void 0===u?I.distance:u,l=i.includeMatches,f=void 0===l?I.includeMatches:l,d=i.findAllMatches,v=void 0===d?I.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?I.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?I.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?I.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},x=this.pattern.length;if(x>P){for(var w=0,L=x%P,S=x-L;w3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?I.location:i,c=r.distance,a=void 0===c?I.distance:c,s=r.threshold,u=void 0===s?I.threshold:s,h=r.findAllMatches,l=void 0===h?I.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?I.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?I.includeMatches:v,y=r.ignoreLocation,p=void 0===y?I.ignoreLocation:y;if(t.length>P)throw new Error(w(P));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,L=b,S=d>1||g,_=S?Array(M):[];(m=e.indexOf(t,L))>-1;){var O=R(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(O,x),L=m+k,S)for(var j=0;j=z;q-=1){var B=q-1,J=n[e.charAt(B)];if(S&&(_[B]=+!!J),K[q]=(K[q+1]<<1|1)&J,F&&(K[q]|=(A[q+1]|A[q])<<1|1|A[q+1]),K[q]&$&&(C=R(t,{errors:F,currentLocation:B,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=C,(L=B)<=b)break;z=Math.max(1,2*b-L)}}if(R(t,{errors:F+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;A=K}var U={isMatch:L>=0,score:Math.max(.001,C)};if(S){var V=N(_,d);V.length?g&&(U.indices=V):U.isMatch=!1}return U}(e,n,i,{location:c+o,distance:a,threshold:s,findAllMatches:u,minMatchCharLength:h,includeMatches:r,ignoreLocation:l}),p=y.isMatch,m=y.score,k=y.indices;p&&(g=!0),v+=m,p&&k&&(d=[].concat(f(d),f(k)))}));var y={isMatch:g,score:g?v/this.chunks.length:1};return g&&r&&(y.indices=d),y}}]),e}(),z=function(){function e(t){r(this,e),this.pattern=t}return o(e,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(e){return D(e,this.multiRegex)}},{key:"isSingleMatch",value:function(e){return D(e,this.singleRegex)}}]),e}();function D(e,t){var n=e.match(t);return n?n[1]:null}var K=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),n}(z),q=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),n}(z),B=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),n}(z),J=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),n}(z),U=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),n}(z),V=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),n}(z),G=function(e){a(n,e);var t=l(n);function n(e){var i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?I.location:c,s=o.threshold,u=void 0===s?I.threshold:s,h=o.distance,l=void 0===h?I.distance:h,f=o.includeMatches,d=void 0===f?I.includeMatches:f,v=o.findAllMatches,g=void 0===v?I.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?I.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?I.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?I.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(z),H=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(z),Q=[K,H,B,J,V,U,q,G],X=Q.length,Y=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;function Z(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(Y).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?I.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?I.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?I.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?I.findAllMatches:f,v=n.location,g=void 0===v?I.location:v,y=n.threshold,p=void 0===y?I.threshold:y,m=n.distance,k=void 0===m?I.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=Z(this.pattern,this.options)}return o(e,[{key:"searchIn",value:function(e){var t=this.query;if(!t)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;e=n.isCaseSensitive?e:e.toLowerCase();for(var i=0,o=[],c=0,a=0,s=t.length;a-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}function ge(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?I.includeMatches:r,o=n.includeScore,c=void 0===o?I.includeScore:o,a=[];return i&&a.push(de),c&&a.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}var ye=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},I),i),this.options.useExtendedSearch,this._keyStore=new S(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof $))throw new Error("Incorrect 'index' type");this._myIndex=t||F(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){k(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,c=i.includeScore,a=i.shouldSort,s=i.sortFn,u=i.ignoreFieldNorm,h=g(e)?g(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return fe(h,{ignoreFieldNorm:u}),a&&h.sort(s),y(r)&&r>-1&&(h=h.slice(0,r)),ge(h,this._docs,{includeMatches:o,includeScore:c})}},{key:"_searchStringList",value:function(e){var t=re(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(k(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=function(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n,i=function e(n){var i=Object.keys(n),o=ue(n);if(!o&&i.length>1&&!se(n))return e(le(n));if(he(n)){var c=o?n[ce]:i[0],a=o?n[ae]:n[c];if(!g(a))throw new Error(x(c));var s={keyId:j(c),pattern:a};return r&&(s.searcher=re(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];v(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u};return se(e)||(e=le(e)),i(e)}(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?I.getFn:n,i=t.fieldNormWeight,o=void 0===i?I.fieldNormWeight:i,c=e.keys,a=e.records,s=new $({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ye.config=I,function(){ne.push.apply(ne,arguments)}(te),ye},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); \ No newline at end of file diff --git a/site_libs/quarto-search/quarto-search.js b/site_libs/quarto-search/quarto-search.js new file mode 100644 index 00000000..d788a958 --- /dev/null +++ b/site_libs/quarto-search/quarto-search.js @@ -0,0 +1,1290 @@ +const kQueryArg = "q"; +const kResultsArg = "show-results"; + +// If items don't provide a URL, then both the navigator and the onSelect +// function aren't called (and therefore, the default implementation is used) +// +// We're using this sentinel URL to signal to those handlers that this +// item is a more item (along with the type) and can be handled appropriately +const kItemTypeMoreHref = "0767FDFD-0422-4E5A-BC8A-3BE11E5BBA05"; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Ensure that search is available on this page. If it isn't, + // should return early and not do anything + var searchEl = window.document.getElementById("quarto-search"); + if (!searchEl) return; + + const { autocomplete } = window["@algolia/autocomplete-js"]; + + let quartoSearchOptions = {}; + let language = {}; + const searchOptionEl = window.document.getElementById( + "quarto-search-options" + ); + if (searchOptionEl) { + const jsonStr = searchOptionEl.textContent; + quartoSearchOptions = JSON.parse(jsonStr); + language = quartoSearchOptions.language; + } + + // note the search mode + if (quartoSearchOptions.type === "overlay") { + searchEl.classList.add("type-overlay"); + } else { + searchEl.classList.add("type-textbox"); + } + + // Used to determine highlighting behavior for this page + // A `q` query param is expected when the user follows a search + // to this page + const currentUrl = new URL(window.location); + const query = currentUrl.searchParams.get(kQueryArg); + const showSearchResults = currentUrl.searchParams.get(kResultsArg); + const mainEl = window.document.querySelector("main"); + + // highlight matches on the page + if (query && mainEl) { + // perform any highlighting + highlight(escapeRegExp(query), mainEl); + + // fix up the URL to remove the q query param + const replacementUrl = new URL(window.location); + replacementUrl.searchParams.delete(kQueryArg); + window.history.replaceState({}, "", replacementUrl); + } + + // function to clear highlighting on the page when the search query changes + // (e.g. if the user edits the query or clears it) + let highlighting = true; + const resetHighlighting = (searchTerm) => { + if (mainEl && highlighting && query && searchTerm !== query) { + clearHighlight(query, mainEl); + highlighting = false; + } + }; + + // Clear search highlighting when the user scrolls sufficiently + const resetFn = () => { + resetHighlighting(""); + window.removeEventListener("quarto-hrChanged", resetFn); + window.removeEventListener("quarto-sectionChanged", resetFn); + }; + + // Register this event after the initial scrolling and settling of events + // on the page + window.addEventListener("quarto-hrChanged", resetFn); + window.addEventListener("quarto-sectionChanged", resetFn); + + // Responsively switch to overlay mode if the search is present on the navbar + // Note that switching the sidebar to overlay mode requires more coordinate (not just + // the media query since we generate different HTML for sidebar overlays than we do + // for sidebar input UI) + const detachedMediaQuery = + quartoSearchOptions.type === "overlay" ? "all" : "(max-width: 991px)"; + + // If configured, include the analytics client to send insights + const plugins = configurePlugins(quartoSearchOptions); + + let lastState = null; + const { setIsOpen, setQuery, setCollections } = autocomplete({ + container: searchEl, + detachedMediaQuery: detachedMediaQuery, + defaultActiveItemId: 0, + panelContainer: "#quarto-search-results", + panelPlacement: quartoSearchOptions["panel-placement"], + debug: false, + openOnFocus: true, + plugins, + classNames: { + form: "d-flex", + }, + placeholder: language["search-text-placeholder"], + translations: { + clearButtonTitle: language["search-clear-button-title"], + detachedCancelButtonText: language["search-detached-cancel-button-title"], + submitButtonTitle: language["search-submit-button-title"], + }, + initialState: { + query, + }, + getItemUrl({ item }) { + return item.href; + }, + onStateChange({ state }) { + // If this is a file URL, note that + + // Perhaps reset highlighting + resetHighlighting(state.query); + + // If the panel just opened, ensure the panel is positioned properly + if (state.isOpen) { + if (lastState && !lastState.isOpen) { + setTimeout(() => { + positionPanel(quartoSearchOptions["panel-placement"]); + }, 150); + } + } + + // Perhaps show the copy link + showCopyLink(state.query, quartoSearchOptions); + + lastState = state; + }, + reshape({ sources, state }) { + return sources.map((source) => { + try { + const items = source.getItems(); + + // Validate the items + validateItems(items); + + // group the items by document + const groupedItems = new Map(); + items.forEach((item) => { + const hrefParts = item.href.split("#"); + const baseHref = hrefParts[0]; + const isDocumentItem = hrefParts.length === 1; + + const items = groupedItems.get(baseHref); + if (!items) { + groupedItems.set(baseHref, [item]); + } else { + // If the href for this item matches the document + // exactly, place this item first as it is the item that represents + // the document itself + if (isDocumentItem) { + items.unshift(item); + } else { + items.push(item); + } + groupedItems.set(baseHref, items); + } + }); + + const reshapedItems = []; + let count = 1; + for (const [_key, value] of groupedItems) { + const firstItem = value[0]; + reshapedItems.push({ + ...firstItem, + type: kItemTypeDoc, + }); + + const collapseMatches = quartoSearchOptions["collapse-after"]; + const collapseCount = + typeof collapseMatches === "number" ? collapseMatches : 1; + + if (value.length > 1) { + const target = `search-more-${count}`; + const isExpanded = + state.context.expanded && + state.context.expanded.includes(target); + + const remainingCount = value.length - collapseCount; + + for (let i = 1; i < value.length; i++) { + if (collapseMatches && i === collapseCount) { + reshapedItems.push({ + target, + title: isExpanded + ? language["search-hide-matches-text"] + : remainingCount === 1 + ? `${remainingCount} ${language["search-more-match-text"]}` + : `${remainingCount} ${language["search-more-matches-text"]}`, + type: kItemTypeMore, + href: kItemTypeMoreHref, + }); + } + + if (isExpanded || !collapseMatches || i < collapseCount) { + reshapedItems.push({ + ...value[i], + type: kItemTypeItem, + target, + }); + } + } + } + count += 1; + } + + return { + ...source, + getItems() { + return reshapedItems; + }, + }; + } catch (error) { + // Some form of error occurred + return { + ...source, + getItems() { + return [ + { + title: error.name || "An Error Occurred While Searching", + text: + error.message || + "An unknown error occurred while attempting to perform the requested search.", + type: kItemTypeError, + }, + ]; + }, + }; + } + }); + }, + navigator: { + navigate({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.location.assign(itemUrl); + } + }, + navigateNewTab({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + const windowReference = window.open(itemUrl, "_blank", "noopener"); + if (windowReference) { + windowReference.focus(); + } + } + }, + navigateNewWindow({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.open(itemUrl, "_blank", "noopener"); + } + }, + }, + getSources({ state, setContext, setActiveItemId, refresh }) { + return [ + { + sourceId: "documents", + getItemUrl({ item }) { + if (item.href) { + return offsetURL(item.href); + } else { + return undefined; + } + }, + onSelect({ + item, + state, + setContext, + setIsOpen, + setActiveItemId, + refresh, + }) { + if (item.type === kItemTypeMore) { + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + + // Toggle more + setIsOpen(true); + } + }, + getItems({ query }) { + if (query === null || query === "") { + return []; + } + + const limit = quartoSearchOptions.limit; + if (quartoSearchOptions.algolia) { + return algoliaSearch(query, limit, quartoSearchOptions.algolia); + } else { + // Fuse search options + const fuseSearchOptions = { + isCaseSensitive: false, + shouldSort: true, + minMatchCharLength: 2, + limit: limit, + }; + + return readSearchData().then(function (fuse) { + return fuseSearch(query, fuse, fuseSearchOptions); + }); + } + }, + templates: { + noResults({ createElement }) { + const hasQuery = lastState.query; + + return createElement( + "div", + { + class: `quarto-search-no-results${ + hasQuery ? "" : " no-query" + }`, + }, + language["search-no-results-text"] + ); + }, + header({ items, createElement }) { + // count the documents + const count = items.filter((item) => { + return item.type === kItemTypeDoc; + }).length; + + if (count > 0) { + return createElement( + "div", + { class: "search-result-header" }, + `${count} ${language["search-matching-documents-text"]}` + ); + } else { + return createElement( + "div", + { class: "search-result-header-no-results" }, + `` + ); + } + }, + footer({ _items, createElement }) { + if ( + quartoSearchOptions.algolia && + quartoSearchOptions.algolia["show-logo"] + ) { + const libDir = quartoSearchOptions.algolia["libDir"]; + const logo = createElement("img", { + src: offsetURL( + `${libDir}/quarto-search/search-by-algolia.svg` + ), + class: "algolia-search-logo", + }); + return createElement( + "a", + { href: "http://www.algolia.com/" }, + logo + ); + } + }, + + item({ item, createElement }) { + return renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh, + quartoSearchOptions + ); + }, + }, + }, + ]; + }, + }); + + window.quartoOpenSearch = () => { + setIsOpen(false); + setIsOpen(true); + focusSearchInput(); + }; + + document.addEventListener("keyup", (event) => { + const { key } = event; + const kbds = quartoSearchOptions["keyboard-shortcut"]; + const focusedEl = document.activeElement; + + const isFormElFocused = [ + "input", + "select", + "textarea", + "button", + "option", + ].find((tag) => { + return focusedEl.tagName.toLowerCase() === tag; + }); + + if ( + kbds && + kbds.includes(key) && + !isFormElFocused && + !document.activeElement.isContentEditable + ) { + event.preventDefault(); + window.quartoOpenSearch(); + } + }); + + // Remove the labeleledby attribute since it is pointing + // to a non-existent label + if (quartoSearchOptions.type === "overlay") { + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + if (inputEl) { + inputEl.removeAttribute("aria-labelledby"); + } + } + + function throttle(func, wait) { + let waiting = false; + return function () { + if (!waiting) { + func.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, wait); + } + }; + } + + // If the main document scrolls dismiss the search results + // (otherwise, since they're floating in the document they can scroll with the document) + window.document.body.onscroll = throttle(() => { + // Only do this if we're not detached + // Bug #7117 + // This will happen when the keyboard is shown on ios (resulting in a scroll) + // which then closed the search UI + if (!window.matchMedia(detachedMediaQuery).matches) { + setIsOpen(false); + } + }, 50); + + if (showSearchResults) { + setIsOpen(true); + focusSearchInput(); + } +}); + +function configurePlugins(quartoSearchOptions) { + const autocompletePlugins = []; + const algoliaOptions = quartoSearchOptions.algolia; + if ( + algoliaOptions && + algoliaOptions["analytics-events"] && + algoliaOptions["search-only-api-key"] && + algoliaOptions["application-id"] + ) { + const apiKey = algoliaOptions["search-only-api-key"]; + const appId = algoliaOptions["application-id"]; + + // Aloglia insights may not be loaded because they require cookie consent + // Use deferred loading so events will start being recorded when/if consent + // is granted. + const algoliaInsightsDeferredPlugin = deferredLoadPlugin(() => { + if ( + window.aa && + window["@algolia/autocomplete-plugin-algolia-insights"] + ) { + window.aa("init", { + appId, + apiKey, + useCookie: true, + }); + + const { createAlgoliaInsightsPlugin } = + window["@algolia/autocomplete-plugin-algolia-insights"]; + // Register the insights client + const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ + insightsClient: window.aa, + onItemsChange({ insights, insightsEvents }) { + const events = insightsEvents.flatMap((event) => { + // This API limits the number of items per event to 20 + const chunkSize = 20; + const itemChunks = []; + const eventItems = event.items; + for (let i = 0; i < eventItems.length; i += chunkSize) { + itemChunks.push(eventItems.slice(i, i + chunkSize)); + } + // Split the items into multiple events that can be sent + const events = itemChunks.map((items) => { + return { + ...event, + items, + }; + }); + return events; + }); + + for (const event of events) { + insights.viewedObjectIDs(event); + } + }, + }); + return algoliaInsightsPlugin; + } + }); + + // Add the plugin + autocompletePlugins.push(algoliaInsightsDeferredPlugin); + return autocompletePlugins; + } +} + +// For plugins that may not load immediately, create a wrapper +// plugin and forward events and plugin data once the plugin +// is initialized. This is useful for cases like cookie consent +// which may prevent the analytics insights event plugin from initializing +// immediately. +function deferredLoadPlugin(createPlugin) { + let plugin = undefined; + let subscribeObj = undefined; + const wrappedPlugin = () => { + if (!plugin && subscribeObj) { + plugin = createPlugin(); + if (plugin && plugin.subscribe) { + plugin.subscribe(subscribeObj); + } + } + return plugin; + }; + + return { + subscribe: (obj) => { + subscribeObj = obj; + }, + onStateChange: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onStateChange) { + plugin.onStateChange(obj); + } + }, + onSubmit: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onSubmit) { + plugin.onSubmit(obj); + } + }, + onReset: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onReset) { + plugin.onReset(obj); + } + }, + getSources: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.getSources) { + return plugin.getSources(obj); + } else { + return Promise.resolve([]); + } + }, + data: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.data) { + plugin.data(obj); + } + }, + }; +} + +function validateItems(items) { + // Validate the first item + if (items.length > 0) { + const item = items[0]; + const missingFields = []; + if (item.href == undefined) { + missingFields.push("href"); + } + if (!item.title == undefined) { + missingFields.push("title"); + } + if (!item.text == undefined) { + missingFields.push("text"); + } + + if (missingFields.length === 1) { + throw { + name: `Error: Search index is missing the ${missingFields[0]} field.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items include the ${missingFields[0]} field or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } else if (missingFields.length > 1) { + const missingFieldList = missingFields + .map((field) => { + return `${field}`; + }) + .join(", "); + + throw { + name: `Error: Search index is missing the following fields: ${missingFieldList}.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items includes the following fields: ${missingFieldList}, or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } + } +} + +let lastQuery = null; +function showCopyLink(query, options) { + const language = options.language; + lastQuery = query; + // Insert share icon + const inputSuffixEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix" + ); + + if (inputSuffixEl) { + let copyButtonEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix .aa-CopyButton" + ); + + if (copyButtonEl === null) { + copyButtonEl = window.document.createElement("button"); + copyButtonEl.setAttribute("class", "aa-CopyButton"); + copyButtonEl.setAttribute("type", "button"); + copyButtonEl.setAttribute("title", language["search-copy-link-title"]); + copyButtonEl.onmousedown = (e) => { + e.preventDefault(); + e.stopPropagation(); + }; + + const linkIcon = "bi-clipboard"; + const checkIcon = "bi-check2"; + + const shareIconEl = window.document.createElement("i"); + shareIconEl.setAttribute("class", `bi ${linkIcon}`); + copyButtonEl.appendChild(shareIconEl); + inputSuffixEl.prepend(copyButtonEl); + + const clipboard = new window.ClipboardJS(".aa-CopyButton", { + text: function (_trigger) { + const copyUrl = new URL(window.location); + copyUrl.searchParams.set(kQueryArg, lastQuery); + copyUrl.searchParams.set(kResultsArg, "1"); + return copyUrl.toString(); + }, + }); + clipboard.on("success", function (e) { + // Focus the input + + // button target + const button = e.trigger; + const icon = button.querySelector("i.bi"); + + // flash "checked" + icon.classList.add(checkIcon); + icon.classList.remove(linkIcon); + setTimeout(function () { + icon.classList.remove(checkIcon); + icon.classList.add(linkIcon); + }, 1000); + }); + } + + // If there is a query, show the link icon + if (copyButtonEl) { + if (lastQuery && options["copy-button"]) { + copyButtonEl.style.display = "flex"; + } else { + copyButtonEl.style.display = "none"; + } + } + } +} + +/* Search Index Handling */ +// create the index +var fuseIndex = undefined; +var shownWarning = false; + +// fuse index options +const kFuseIndexOptions = { + keys: [ + { name: "title", weight: 20 }, + { name: "section", weight: 20 }, + { name: "text", weight: 10 }, + ], + ignoreLocation: true, + threshold: 0.1, +}; + +async function readSearchData() { + // Initialize the search index on demand + if (fuseIndex === undefined) { + if (window.location.protocol === "file:" && !shownWarning) { + window.alert( + "Search requires JavaScript features disabled when running in file://... URLs. In order to use search, please run this document in a web server." + ); + shownWarning = true; + return; + } + const fuse = new window.Fuse([], kFuseIndexOptions); + + // fetch the main search.json + const response = await fetch(offsetURL("search.json")); + if (response.status == 200) { + return response.json().then(function (searchDocs) { + searchDocs.forEach(function (searchDoc) { + fuse.add(searchDoc); + }); + fuseIndex = fuse; + return fuseIndex; + }); + } else { + return Promise.reject( + new Error( + "Unexpected status from search index request: " + response.status + ) + ); + } + } + + return fuseIndex; +} + +function inputElement() { + return window.document.body.querySelector(".aa-Form .aa-Input"); +} + +function focusSearchInput() { + setTimeout(() => { + const inputEl = inputElement(); + if (inputEl) { + inputEl.focus(); + } + }, 50); +} + +/* Panels */ +const kItemTypeDoc = "document"; +const kItemTypeMore = "document-more"; +const kItemTypeItem = "document-item"; +const kItemTypeError = "error"; + +function renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh, + quartoSearchOptions +) { + switch (item.type) { + case kItemTypeDoc: + return createDocumentCard( + createElement, + "file-richtext", + item.title, + item.section, + item.text, + item.href, + item.crumbs, + quartoSearchOptions + ); + case kItemTypeMore: + return createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh + ); + case kItemTypeItem: + return createSectionCard( + createElement, + item.section, + item.text, + item.href + ); + case kItemTypeError: + return createErrorCard(createElement, item.title, item.text); + default: + return undefined; + } +} + +function createDocumentCard( + createElement, + icon, + title, + section, + text, + href, + crumbs, + quartoSearchOptions +) { + const iconEl = createElement("i", { + class: `bi bi-${icon} search-result-icon`, + }); + const titleEl = createElement("p", { class: "search-result-title" }, title); + const titleContents = [iconEl, titleEl]; + const showParent = quartoSearchOptions["show-item-context"]; + if (crumbs && showParent) { + let crumbsOut = undefined; + const crumbClz = ["search-result-crumbs"]; + if (showParent === "root") { + crumbsOut = crumbs.length > 1 ? crumbs[0] : undefined; + } else if (showParent === "parent") { + crumbsOut = crumbs.length > 1 ? crumbs[crumbs.length - 2] : undefined; + } else { + crumbsOut = crumbs.length > 1 ? crumbs.join(" > ") : undefined; + crumbClz.push("search-result-crumbs-wrap"); + } + + const crumbEl = createElement( + "p", + { class: crumbClz.join(" ") }, + crumbsOut + ); + titleContents.push(crumbEl); + } + + const titleContainerEl = createElement( + "div", + { class: "search-result-title-container" }, + titleContents + ); + + const textEls = []; + if (section) { + const sectionEl = createElement( + "p", + { class: "search-result-section" }, + section + ); + textEls.push(sectionEl); + } + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + textEls.push(descEl); + + const textContainerEl = createElement( + "div", + { class: "search-result-text-container" }, + textEls + ); + + const containerEl = createElement( + "div", + { + class: "search-result-container", + }, + [titleContainerEl, textContainerEl] + ); + + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + containerEl + ); + + const classes = ["search-result-doc", "search-item"]; + if (!section) { + classes.push("document-selectable"); + } + + return createElement( + "div", + { + class: classes.join(" "), + }, + linkEl + ); +} + +function createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh +) { + const moreCardEl = createElement( + "div", + { + class: "search-result-more search-item", + onClick: (e) => { + // Handle expanding the sections by adding the expanded + // section to the list of expanded sections + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + e.stopPropagation(); + }, + }, + item.title + ); + + return moreCardEl; +} + +function toggleExpanded(item, state, setContext, setActiveItemId, refresh) { + const expanded = state.context.expanded || []; + if (expanded.includes(item.target)) { + setContext({ + expanded: expanded.filter((target) => target !== item.target), + }); + } else { + setContext({ expanded: [...expanded, item.target] }); + } + + refresh(); + setActiveItemId(item.__autocomplete_id); +} + +function createSectionCard(createElement, section, text, href) { + const sectionEl = createSection(createElement, section, text, href); + return createElement( + "div", + { + class: "search-result-doc-section search-item", + }, + sectionEl + ); +} + +function createSection(createElement, title, text, href) { + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { class: "search-result-section" }, title); + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + [titleEl, descEl] + ); + return linkEl; +} + +function createErrorCard(createElement, title, text) { + const descEl = createElement("p", { + class: "search-error-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { + class: "search-error-title", + dangerouslySetInnerHTML: { + __html: ` ${title}`, + }, + }); + const errorEl = createElement("div", { class: "search-error" }, [ + titleEl, + descEl, + ]); + return errorEl; +} + +function positionPanel(pos) { + const panelEl = window.document.querySelector( + "#quarto-search-results .aa-Panel" + ); + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + + if (panelEl && inputEl) { + panelEl.style.top = `${Math.round(panelEl.offsetTop)}px`; + if (pos === "start") { + panelEl.style.left = `${Math.round(inputEl.left)}px`; + } else { + panelEl.style.right = `${Math.round(inputEl.offsetRight)}px`; + } + } +} + +/* Highlighting */ +// highlighting functions +function highlightMatch(query, text) { + if (text) { + const start = text.toLowerCase().indexOf(query.toLowerCase()); + if (start !== -1) { + const startMark = ""; + const endMark = ""; + + const end = start + query.length; + text = + text.slice(0, start) + + startMark + + text.slice(start, end) + + endMark + + text.slice(end); + const startInfo = clipStart(text, start); + const endInfo = clipEnd( + text, + startInfo.position + startMark.length + endMark.length + ); + text = + startInfo.prefix + + text.slice(startInfo.position, endInfo.position) + + endInfo.suffix; + + return text; + } else { + return text; + } + } else { + return text; + } +} + +function clipStart(text, pos) { + const clipStart = pos - 50; + if (clipStart < 0) { + // This will just return the start of the string + return { + position: 0, + prefix: "", + }; + } else { + // We're clipping before the start of the string, walk backwards to the first space. + const spacePos = findSpace(text, pos, -1); + return { + position: spacePos.position, + prefix: "", + }; + } +} + +function clipEnd(text, pos) { + const clipEnd = pos + 200; + if (clipEnd > text.length) { + return { + position: text.length, + suffix: "", + }; + } else { + const spacePos = findSpace(text, clipEnd, 1); + return { + position: spacePos.position, + suffix: spacePos.clipped ? "…" : "", + }; + } +} + +function findSpace(text, start, step) { + let stepPos = start; + while (stepPos > -1 && stepPos < text.length) { + const char = text[stepPos]; + if (char === " " || char === "," || char === ":") { + return { + position: step === 1 ? stepPos : stepPos - step, + clipped: stepPos > 1 && stepPos < text.length, + }; + } + stepPos = stepPos + step; + } + + return { + position: stepPos - step, + clipped: false, + }; +} + +// removes highlighting as implemented by the mark tag +function clearHighlight(searchterm, el) { + const childNodes = el.childNodes; + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + if (node.nodeType === Node.ELEMENT_NODE) { + if ( + node.tagName === "MARK" && + node.innerText.toLowerCase() === searchterm.toLowerCase() + ) { + el.replaceChild(document.createTextNode(node.innerText), node); + } else { + clearHighlight(searchterm, node); + } + } + } +} + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string +} + +// highlight matches +function highlight(term, el) { + const termRegex = new RegExp(term, "ig"); + const childNodes = el.childNodes; + + // walk back to front avoid mutating elements in front of us + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + + if (node.nodeType === Node.TEXT_NODE) { + // Search text nodes for text to highlight + const text = node.nodeValue; + + let startIndex = 0; + let matchIndex = text.search(termRegex); + if (matchIndex > -1) { + const markFragment = document.createDocumentFragment(); + while (matchIndex > -1) { + const prefix = text.slice(startIndex, matchIndex); + markFragment.appendChild(document.createTextNode(prefix)); + + const mark = document.createElement("mark"); + mark.appendChild( + document.createTextNode( + text.slice(matchIndex, matchIndex + term.length) + ) + ); + markFragment.appendChild(mark); + + startIndex = matchIndex + term.length; + matchIndex = text.slice(startIndex).search(new RegExp(term, "ig")); + if (matchIndex > -1) { + matchIndex = startIndex + matchIndex; + } + } + if (startIndex < text.length) { + markFragment.appendChild( + document.createTextNode(text.slice(startIndex, text.length)) + ); + } + + el.replaceChild(markFragment, node); + } + } else if (node.nodeType === Node.ELEMENT_NODE) { + // recurse through elements + highlight(term, node); + } + } +} + +/* Link Handling */ +// get the offset from this page for a given site root relative url +function offsetURL(url) { + var offset = getMeta("quarto:offset"); + return offset ? offset + url : url; +} + +// read a meta tag value +function getMeta(metaName) { + var metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; +} + +function algoliaSearch(query, limit, algoliaOptions) { + const { getAlgoliaResults } = window["@algolia/autocomplete-preset-algolia"]; + + const applicationId = algoliaOptions["application-id"]; + const searchOnlyApiKey = algoliaOptions["search-only-api-key"]; + const indexName = algoliaOptions["index-name"]; + const indexFields = algoliaOptions["index-fields"]; + const searchClient = window.algoliasearch(applicationId, searchOnlyApiKey); + const searchParams = algoliaOptions["params"]; + const searchAnalytics = !!algoliaOptions["analytics-events"]; + + return getAlgoliaResults({ + searchClient, + queries: [ + { + indexName: indexName, + query, + params: { + hitsPerPage: limit, + clickAnalytics: searchAnalytics, + ...searchParams, + }, + }, + ], + transformResponse: (response) => { + if (!indexFields) { + return response.hits.map((hit) => { + return hit.map((item) => { + return { + ...item, + text: highlightMatch(query, item.text), + }; + }); + }); + } else { + const remappedHits = response.hits.map((hit) => { + return hit.map((item) => { + const newItem = { ...item }; + ["href", "section", "title", "text", "crumbs"].forEach( + (keyName) => { + const mappedName = indexFields[keyName]; + if ( + mappedName && + item[mappedName] !== undefined && + mappedName !== keyName + ) { + newItem[keyName] = item[mappedName]; + delete newItem[mappedName]; + } + } + ); + newItem.text = highlightMatch(query, newItem.text); + return newItem; + }); + }); + return remappedHits; + } + }, + }); +} + +let subSearchTerm = undefined; +let subSearchFuse = undefined; +const kFuseMaxWait = 125; + +async function fuseSearch(query, fuse, fuseOptions) { + let index = fuse; + // Fuse.js using the Bitap algorithm for text matching which runs in + // O(nm) time (no matter the structure of the text). In our case this + // means that long search terms mixed with large index gets very slow + // + // This injects a subIndex that will be used once the terms get long enough + // Usually making this subindex is cheap since there will typically be + // a subset of results matching the existing query + if (subSearchFuse !== undefined && query.startsWith(subSearchTerm)) { + // Use the existing subSearchFuse + index = subSearchFuse; + } else if (subSearchFuse !== undefined) { + // The term changed, discard the existing fuse + subSearchFuse = undefined; + subSearchTerm = undefined; + } + + // Search using the active fuse + const then = performance.now(); + const resultsRaw = await index.search(query, fuseOptions); + const now = performance.now(); + + const results = resultsRaw.map((result) => { + const addParam = (url, name, value) => { + const anchorParts = url.split("#"); + const baseUrl = anchorParts[0]; + const sep = baseUrl.search("\\?") > 0 ? "&" : "?"; + anchorParts[0] = baseUrl + sep + name + "=" + value; + return anchorParts.join("#"); + }; + + return { + title: result.item.title, + section: result.item.section, + href: addParam(result.item.href, kQueryArg, query), + text: highlightMatch(query, result.item.text), + crumbs: result.item.crumbs, + }; + }); + + // If we don't have a subfuse and the query is long enough, go ahead + // and create a subfuse to use for subsequent queries + if ( + now - then > kFuseMaxWait && + subSearchFuse === undefined && + resultsRaw.length < fuseOptions.limit + ) { + subSearchTerm = query; + subSearchFuse = new window.Fuse([], kFuseIndexOptions); + resultsRaw.forEach((rr) => { + subSearchFuse.add(rr.item); + }); + } + return results; +} diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..c972b919 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,71 @@ + + + + https://fastcore.fast.ai/xml.html + 2024-08-15T16:43:55.279Z + + + https://fastcore.fast.ai/net.html + 2024-08-15T16:43:55.155Z + + + https://fastcore.fast.ai/test.html + 2024-08-15T16:43:56.571Z + + + https://fastcore.fast.ai/xdg.html + 2024-08-15T16:43:54.891Z + + + https://fastcore.fast.ai/meta.html + 2024-08-15T16:43:54.931Z + + + https://fastcore.fast.ai/script.html + 2024-08-15T16:43:54.627Z + + + https://fastcore.fast.ai/parallel.html + 2024-08-15T16:43:54.515Z + + + https://fastcore.fast.ai/tour.html + 2024-08-15T16:43:49.771Z + + + https://fastcore.fast.ai/style.html + 2024-08-15T16:43:49.783Z + + + https://fastcore.fast.ai/basics.html + 2024-08-15T16:43:55.367Z + + + https://fastcore.fast.ai/xtras.html + 2024-08-15T16:43:54.755Z + + + https://fastcore.fast.ai/foundation.html + 2024-08-15T16:43:54.811Z + + + https://fastcore.fast.ai/py2pyi.html + 2024-08-15T16:43:54.767Z + + + https://fastcore.fast.ai/dispatch.html + 2024-08-15T16:43:54.923Z + + + https://fastcore.fast.ai/index.html + 2024-08-15T16:43:54.927Z + + + https://fastcore.fast.ai/transform.html + 2024-08-15T16:43:55.147Z + + + https://fastcore.fast.ai/docments.html + 2024-08-15T16:43:55.263Z + + diff --git a/style.html b/style.html new file mode 100644 index 00000000..2f3f8ba3 --- /dev/null +++ b/style.html @@ -0,0 +1,876 @@ + + + + + + + + + + +Style – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + +
+ + + +
+ +
+
+

Style

+
+ +
+
+ Fast styling for friendly CLIs. +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
+
+ +
+
+Note +
+
+
+

Styled outputs don’t show in Quarto documentation. Please use a notebook editor to correctly view this page.

+
+
+
+

source

+
+

StyleCode

+
+
 StyleCode (name, code, typ)
+
+

An escape sequence for styling terminal text.

+

The primary building block of the S API.

+
+
print(str(StyleCode('blue', 34, 'fg')) + 'hello' + str(StyleCode('default', 39, 'fg')) + ' world')
+
+
hello world
+
+
+
+

source

+
+
+

Style

+
+
 Style (codes=None)
+
+

A minimal terminal text styler.

+

The main way to use it is via the exported S object.

+
+
+Exported source +
S = Style()
+
+
+

We start with an empty style:

+
+
S
+
+
<Style: none>
+
+
+

Define a new style by chaining attributes:

+
+
s = S.blue.bold.underline
+s
+
+
<Style: blue bold underline>
+
+
+

You can see a full list of available styles with auto-complete by typing S . Tab.

+

Apply a style by calling it with a string:

+
+
s('hello world')
+
+
'\x1b[34m\x1b[1m\x1b[4mhello world\x1b[22m\x1b[24m\x1b[39m'
+
+
+

That’s a raw string with the underlying escape sequences that tell the terminal how to format text. To see the styled version we have to print it:

+
+
print(s('hello world'))
+
+
hello world
+
+
+

You can also nest styles:

+
+
print(S.bold(S.blue('key') + ' = value ') + S.light_gray(' ' + S.underline('# With a comment')) + ' and unstyled text')
+
+
key = value  # With a comment and unstyled text
+
+
+
+
print(S.blue('this '+S.bold('is')+' a test'))
+
+
this is a test
+
+
+
+

source

+
+
+

demo

+
+
 demo ()
+
+

Demonstrate all available styles and their codes.

+
+
demo()
+
+
 30    black           
+ 31    red             
+ 32    green           
+ 33    yellow          
+ 34    blue            
+ 35    magenta         
+ 36    cyan            
+ 37    light_gray      
+ 39    default         
+ 90    dark_gray       
+ 91    light_red       
+ 92    light_green     
+ 93    light_yellow    
+ 94    light_blue      
+ 95    light_magenta   
+ 96    light_cyan      
+ 97    white           
+ 40    black_bg        
+ 41    red_bg          
+ 42    green_bg        
+ 43    yellow_bg       
+ 44    blue_bg         
+ 45    magenta_bg      
+ 46    cyan_bg         
+ 47    light_gray_bg   
+ 49    default_bg      
+100    dark_gray_bg    
+101    light_red_bg    
+102    light_green_bg  
+103    light_yellow_bg 
+104    light_blue_bg   
+105    light_magenta_bg
+106    light_cyan_bg   
+107    white_bg        
+  1    bold            
+  2    dim             
+  3    italic          
+  4    underline       
+  5    blink           
+  7    invert          
+  8    hidden          
+  9    strikethrough   
+ 22    reset_bold      
+ 22    reset_dim       
+ 23    reset_italic    
+ 24    reset_underline 
+ 25    reset_blink     
+ 27    reset_invert    
+ 28    reset_hidden    
+ 29    reset_strikethrough
+  0    reset           
+
+
+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 00000000..b46c2093 --- /dev/null +++ b/styles.css @@ -0,0 +1,18 @@ +.cell-output pre { + margin-left: 0.8rem; + margin-top: 0; + background: none; + border-left: 2px solid lightsalmon; + border-top-left-radius: 0; + border-top-right-radius: 0; + } + + .cell-output .sourceCode { + background: none; + margin-top: 0; + } + + .cell > .sourceCode { + margin-bottom: 0; + } + \ No newline at end of file diff --git a/test.html b/test.html new file mode 100644 index 00000000..649a80b7 --- /dev/null +++ b/test.html @@ -0,0 +1,1062 @@ + + + + + + + + + + +Test – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Test

+
+ +
+
+ Helper functions to quickly write tests in notebooks +
+
+ + +
+ + + + +
+ + + +
+ + + +
+

Simple test functions

+

We can check that code raises an exception when that’s expected (test_fail).

+

To test for equality or inequality (with different types of things) we define a simple function test that compares two objects with a given cmp operator.

+
+

source

+
+

test_fail

+
+
 test_fail (f, msg='', contains='', args=None, kwargs=None)
+
+

Fails with msg unless f() raises an exception and (optionally) has contains in e.args

+
+
def _fail(): raise Exception("foobar")
+test_fail(_fail, contains="foo")
+
+def _fail(): raise Exception()
+test_fail(_fail)
+
+

We can also pass args and kwargs to function to check if it fails with special inputs.

+
+
def _fail_args(a):
+    if a == 5:
+        raise ValueError
+test_fail(_fail_args, args=(5,))
+test_fail(_fail_args, kwargs=dict(a=5))
+
+
+

source

+
+
+

test

+
+
 test (a, b, cmp, cname=None)
+
+

assert that cmp(a,b); display inputs and cname or cmp.__name__ if it fails

+
+
test([1,2],[1,2], operator.eq)
+test_fail(lambda: test([1,2],[1], operator.eq))
+test([1,2],[1],   operator.ne)
+test_fail(lambda: test([1,2],[1,2], operator.ne))
+
+
+
+
+

all_equal

+
+
 all_equal (a, b)
+
+

Compares whether a and b are the same length and have the same contents

+
+
test(['abc'], ['abc'], all_equal)
+test_fail(lambda: test(['abc'],['cab'], all_equal))
+
+
+
+
+

equals

+
+
 equals (a, b)
+
+

Compares a and b for equality; supports sublists, tensors and arrays too

+
+
test([['abc'],['a']], [['abc'],['a']],  equals)
+test([['abc'],['a'],'b', [['x']]], [['abc'],['a'],'b', [['x']]],  equals) # supports any depth and nested structure
+
+
+

source

+
+
+

nequals

+
+
 nequals (a, b)
+
+

Compares a and b for not equals

+
+
test(['abc'], ['ab' ], nequals)
+
+
+
+
+

test_eq test_ne, etc…

+

Just use test_eq/test_ne to test for ==/!=. test_eq_type checks things are equal and of the same type. We define them using test:

+
+

source

+
+

test_eq

+
+
 test_eq (a, b)
+
+

test that a==b

+
+
test_eq([1,2],[1,2])
+test_eq([1,2],map(int,[1,2]))
+test_eq(array([1,2]),array([1,2]))
+test_eq(array([1,2]),array([1,2]))
+test_eq([array([1,2]),3],[array([1,2]),3])
+test_eq(dict(a=1,b=2), dict(b=2,a=1))
+test_fail(lambda: test_eq([1,2], 1), contains="==")
+test_fail(lambda: test_eq(None, np.array([1,2])), contains="==")
+test_eq({'a', 'b', 'c'}, {'c', 'a', 'b'})
+
+
+
df1 = pd.DataFrame(dict(a=[1,2],b=['a','b']))
+df2 = pd.DataFrame(dict(a=[1,2],b=['a','b']))
+df3 = pd.DataFrame(dict(a=[1,2],b=['a','c']))
+
+test_eq(df1,df2)
+test_eq(df1.a,df2.a)
+test_fail(lambda: test_eq(df1,df3), contains='==')
+class T(pd.Series): pass
+test_eq(df1.iloc[0], T(df2.iloc[0])) # works with subclasses
+
+
+
test_eq(torch.zeros(10), torch.zeros(10, dtype=torch.float64))
+test_eq(torch.zeros(10), torch.ones(10)-1)
+test_fail(lambda:test_eq(torch.zeros(10), torch.ones(1, 10)), contains='==')
+test_eq(torch.zeros(3), [0,0,0])
+
+
+

source

+
+
+

test_eq_type

+
+
 test_eq_type (a, b)
+
+

test that a==b and are same type

+
+
test_eq_type(1,1)
+test_fail(lambda: test_eq_type(1,1.))
+test_eq_type([1,1],[1,1])
+test_fail(lambda: test_eq_type([1,1],(1,1)))
+test_fail(lambda: test_eq_type([1,1],[1,1.]))
+
+
+

source

+
+
+

test_ne

+
+
 test_ne (a, b)
+
+

test that a!=b

+
+
test_ne([1,2],[1])
+test_ne([1,2],[1,3])
+test_ne(array([1,2]),array([1,1]))
+test_ne(array([1,2]),array([1,1]))
+test_ne([array([1,2]),3],[array([1,2])])
+test_ne([3,4],array([3]))
+test_ne([3,4],array([3,5]))
+test_ne(dict(a=1,b=2), ['a', 'b'])
+test_ne(['a', 'b'], dict(a=1,b=2))
+
+
+

source

+
+
+

is_close

+
+
 is_close (a, b, eps=1e-05)
+
+

Is a within eps of b

+
+

source

+
+
+

test_close

+
+
 test_close (a, b, eps=1e-05)
+
+

test that a is within eps of b

+
+
test_close(1,1.001,eps=1e-2)
+test_fail(lambda: test_close(1,1.001))
+test_close([-0.001,1.001], [0.,1.], eps=1e-2)
+test_close(np.array([-0.001,1.001]), np.array([0.,1.]), eps=1e-2)
+test_close(array([-0.001,1.001]), array([0.,1.]), eps=1e-2)
+
+
+

source

+
+
+

test_is

+
+
 test_is (a, b)
+
+

test that a is b

+
+
test_fail(lambda: test_is([1], [1]))
+a = [1]
+test_is(a, a)
+b = [2]; test_fail(lambda: test_is(a, b))
+
+
+

source

+
+
+

test_shuffled

+
+
 test_shuffled (a, b)
+
+

test that a and b are shuffled versions of the same sequence of items

+
+
a = list(range(50))
+b = copy(a)
+random.shuffle(b)
+test_shuffled(a,b)
+test_fail(lambda:test_shuffled(a,a))
+
+
+
a = 'abc'
+b = 'abcabc'
+test_fail(lambda:test_shuffled(a,b))
+
+
+
a = ['a', 42, True] 
+b = [42, True, 'a']
+test_shuffled(a,b)
+
+
+

source

+
+
+

test_stdout

+
+
 test_stdout (f, exp, regex=False)
+
+

Test that f prints exp to stdout, optionally checking as regex

+
+
test_stdout(lambda: print('hi'), 'hi')
+test_fail(lambda: test_stdout(lambda: print('hi'), 'ho'))
+test_stdout(lambda: 1+1, '')
+test_stdout(lambda: print('hi there!'), r'^hi.*!$', regex=True)
+
+
+

source

+
+
+

test_warns

+
+
 test_warns (f, show=False)
+
+
+
test_warns(lambda: warnings.warn("Oh no!"))
+test_fail(lambda: test_warns(lambda: 2+2), contains='No warnings raised')
+
+
+
test_warns(lambda: warnings.warn("Oh no!"), show=True)
+
+
<class 'UserWarning'>: Oh no!
+
+
+
+
im = Image.open(TEST_IMAGE).resize((128,128)); im
+
+
+
+

+
+
+
+
+
+
im = Image.open(TEST_IMAGE_BW).resize((128,128)); im
+
+
+
+

+
+
+
+
+
+

source

+
+
+

test_fig_exists

+
+
 test_fig_exists (ax)
+
+

Test there is a figure displayed in ax

+
+
fig,ax = plt.subplots()
+ax.imshow(array(im));
+
+
+
+

+
+
+
+
+
+
test_fig_exists(ax)
+
+
+

source

+
+
+

ExceptionExpected

+
+
 ExceptionExpected (ex=<class 'Exception'>, regex='')
+
+

Context manager that tests if an exception is raised

+
+
def _tst_1(): assert False, "This is a test"
+def _tst_2(): raise SyntaxError
+
+with ExceptionExpected(): _tst_1()
+with ExceptionExpected(ex=AssertionError, regex="This is a test"): _tst_1()
+with ExceptionExpected(ex=SyntaxError): _tst_2()
+
+

exception is an abbreviation for ExceptionExpected().

+
+
with exception: _tst_1()
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/tour.html b/tour.html new file mode 100644 index 00000000..820e01af --- /dev/null +++ b/tour.html @@ -0,0 +1,936 @@ + + + + + + + + + +A tour of fastcore – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

A tour of fastcore

+
+ + + +
+ + + + +
+ + + +
+ + + +

Here’s a (somewhat) quick tour of a few higlights from fastcore.

+
+

Documentation

+

All fast.ai projects, including this one, are built with nbdev, which is a full literate programming environment built on Jupyter Notebooks. That means that every piece of documentation, including the page you’re reading now, can be accessed as interactive Jupyter notebooks. In fact, you can even grab a link directly to a notebook running interactively on Google Colab - if you want to follow along with this tour, click the link below:

+
+
colab_link('index')
+ +
+

The full docs are available at fastcore.fast.ai. The code in the examples and in all fast.ai libraries follow the fast.ai style guide. In order to support interactive programming, all fast.ai libraries are designed to allow for import * to be used safely, particular by ensuring that __all__ is defined in all packages. In order to see where a function is from, just type it:

+
+
coll_repr
+
+
<function fastcore.foundation.coll_repr(c, max_n=10)>
+
+
+

For more details, including a link to the full documentation and source code, use doc, which pops up a window with this information:

+
doc(coll_repr)
+

+

The documentation also contains links to any related functions or classes, which appear like this: coll_repr (in the notebook itself you will just see a word with back-ticks around it; the links are auto-generated in the documentation site). The documentation will generally show one or more examples of use, along with any background context necessary to understand them. As you’ll see, the examples for each function and method are shown as tests, rather than example outputs, so let’s start by explaining that.

+
+
+

Testing

+

fastcore’s testing module is designed to work well with nbdev, which is a full literate programming environment built on Jupyter Notebooks. That means that your tests, docs, and code all live together in the same notebook. fastcore and nbdev’s approach to testing starts with the premise that all your tests should pass. If one fails, no more tests in a notebook are run.

+

Tests look like this:

+
+
test_eq(coll_repr(range(1000), 5), '(#1000) [0,1,2,3,4...]')
+
+

That’s an example from the docs for coll_repr. As you see, it’s not showing you the output directly. Here’s what that would look like:

+
+
coll_repr(range(1000), 5)
+
+
'(#1000) [0,1,2,3,4...]'
+
+
+

So, the test is actually showing you what the output looks like, because if the function call didn’t return '(#1000) [0,1,2,3,4...]', then the test would have failed.

+

So every test shown in the docs is also showing you the behavior of the library — and vice versa!

+

Test functions always start with test_, and then follow with the operation being tested. So test_eq tests for equality (as you saw in the example above). This includes tests for equality of arrays and tensors, lists and generators, and many more:

+
+
test_eq([0,1,2,3], np.arange(4))
+
+

When a test fails, it prints out information about what was expected:

+
test_eq([0,1,2,3], np.arange(3))
+
----
+  AssertionError: ==:
+  [0, 1, 2, 3]
+  [0 1 2]
+

If you want to check that objects are the same type, rather than the just contain the same collection, use test_eq_type.

+

You can test with any comparison function using test, e.g test whether an object is less than:

+
+
test(2, 3, operator.lt)
+
+

You can even test that exceptions are raised:

+
+
def divide_zero(): return 1/0
+test_fail(divide_zero)
+
+

…and test that things are printed to stdout:

+
+
test_stdout(lambda: print('hi'), 'hi')
+
+
+
+

Foundations

+

fast.ai is unusual in that we often use mixins in our code. Mixins are widely used in many programming languages, such as Ruby, but not so much in Python. We use mixins to attach new behavior to existing libraries, or to allow modules to add new behavior to our own classes, such as in extension modules. One useful example of a mixin we define is Path.ls, which lists a directory and returns an L (an extended list class which we’ll discuss shortly):

+
+
p = Path('images')
+p.ls()
+
+
(#6) [Path('images/mnist3.png'),Path('images/att_00000.png'),Path('images/puppy.jpg'),Path('images/att_00005.png'),Path('images/att_00007.png'),Path('images/att_00006.png')]
+
+
+

You can easily add you own mixins with the patch decorator, which takes advantage of Python 3 function annotations to say what class to patch:

+
+
@patch
+def num_items(self:Path): return len(self.ls())
+
+p.num_items()
+
+
6
+
+
+

We also use **kwargs frequently. In python **kwargs in a parameter like means “put any additional keyword arguments into a dict called kwargs”. Normally, using kwargs makes an API quite difficult to work with, because it breaks things like tab-completion and popup lists of signatures. utils provides use_kwargs and delegates to avoid this problem. See our detailed article on delegation on this topic.

+

GetAttr solves a similar problem (and is also discussed in the article linked above): it’s allows you to use Python’s exceptionally useful __getattr__ magic method, but avoids the problem that normally in Python tab-completion and docs break when using this. For instance, you can see here that Python’s dir function, which is used to find the attributes of a python object, finds everything inside the self.default attribute here:

+
+
class Author:
+    def __init__(self, name): self.name = name
+
+class ProductPage(GetAttr):
+    _default = 'author'
+    def __init__(self,author,price,cost): self.author,self.price,self.cost = author,price,cost
+
+p = ProductPage(Author("Jeremy"), 1.50, 0.50)
+[o for o in dir(p) if not o.startswith('_')]
+
+
['author', 'cost', 'name', 'price']
+
+
+

Looking at that ProductPage example, it’s rather verbose and duplicates a lot of attribute names, which can lead to bugs later if you change them only in one place. fastcore provides store_attr to simplify this common pattern. It also provides basic_repr to give simple objects a useful repr:

+
+
class ProductPage:
+    def __init__(self,author,price,cost): store_attr()
+    __repr__ = basic_repr('author,price,cost')
+
+ProductPage("Jeremy", 1.50, 0.50)
+
+
__main__.ProductPage(author='Jeremy', price=1.5, cost=0.5)
+
+
+

One of the most interesting fastcore functions is the funcs_kwargs decorator. This allows class behavior to be modified without sub-classing. This can allow folks that aren’t familiar with object-oriented programming to customize your class more easily. Here’s an example of a class that uses funcs_kwargs:

+
+
@funcs_kwargs
+class T:
+    _methods=['some_method']
+    def __init__(self, **kwargs): assert not kwargs, f'Passed unknown args: {kwargs}'
+
+p = T(some_method = print)
+p.some_method("hello")
+
+
hello
+
+
+

The assert not kwargs above is used to ensure that the user doesn’t pass an unknown parameter (i.e one that’s not in _methods). fastai uses funcs_kwargs in many places, for instance, you can customize any part of a DataLoader by passing your own methods.

+

fastcore also provides many utility functions that make a Python programmer’s life easier, in fastcore.utils. We won’t look at many here, since you can easily look at the docs yourself. To get you started, have a look at the docs for chunked (remember, if you’re in a notebook, type doc(chunked)), which is a handy function for creating lazily generated batches from a collection.

+

Python’s ProcessPoolExecutor is extended to allow max_workers to be set to 0, to easily turn off parallel processing. This makes it easy to debug your code in serial, then run it in parallel. It also allows you to pass arguments to your parallel function, and to ensure there’s a pause between calls, in case the process you are running has race conditions. parallel makes parallel processing even easier to use, and even adds an optional progress bar.

+
+
+

L

+

Like most languages, Python allows for very concise syntax for some very common types, such as list, which can be constructed with [1,2,3]. Perl’s designer Larry Wall explained the reasoning for this kind of syntax:

+
+

In metaphorical honor of Huffman’s compression code that assigns smaller numbers of bits to more common bytes. In terms of syntax, it simply means that commonly used things should be shorter, but you shouldn’t waste short sequences on less common constructs.

+
+

On this basis, fastcore has just one type that has a single letter name: L. The reason for this is that it is designed to be a replacement for list, so we want it to be just as easy to use as [1,2,3]. Here’s how to create that as an L:

+
+
L(1,2,3)
+
+
(#3) [1,2,3]
+
+
+

The first thing to notice is that an L object includes in its representation its number of elements; that’s the (#3) in the output above. If there’s more than 10 elements, it will automatically truncate the list:

+
+
p = L.range(20).shuffle()
+p
+
+
(#20) [5,1,9,10,18,13,6,17,3,16...]
+
+
+

L contains many of the same indexing ideas that NumPy’s array does, including indexing with a list of indexes, or a boolean mask list:

+
+
p[2,4,6]
+
+
(#3) [9,18,6]
+
+
+

It also contains other methods used in array, such as L.argwhere:

+
+
p.argwhere(ge(15))
+
+
(#5) [4,7,9,18,19]
+
+
+

As you can see from this example, fastcore also includes a number of features that make a functional style of programming easier, such as a full range of boolean functions (e.g ge, gt, etc) which give the same answer as the functions from Python’s operator module if given two parameters, but return a curried function if given one parameter.

+

There’s too much functionality to show it all here, so be sure to check the docs. Many little things are added that we thought should have been in list in the first place, such as making this do what you’d expect (which is an error with list, but works fine with L):

+
+
1 + L(2,3,4)
+
+
(#4) [1,2,3,4]
+
+
+
+
+

Transforms

+

A Transform is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the Transform class provides several mechanisms that make the process of building them easy and flexible (see the docs for information about each of these):

+
    +
  • Type dispatch
  • +
  • Dispatch over tuples
  • +
  • Reversability
  • +
  • Type propagation
  • +
  • Preprocessing
  • +
  • Filtering based on the dataset type
  • +
  • Ordering
  • +
  • Appending new behavior with decorators
  • +
+

Transform looks for three special methods, encodes, decodes, and setups, which provide the implementation for __call__, decode, and setup respectively. For instance:

+
+
class A(Transform):
+    def encodes(self, x): return x+1
+
+A()(1)
+
+
2
+
+
+

For simple transforms like this, you can also use Transform as a decorator:

+
+
@Transform
+def f(x): return x+1
+
+f(1)
+
+
2
+
+
+

Transforms can be composed into a Pipeline:

+
+
@Transform
+def g(x): return x/2
+
+pipe = Pipeline([f,g])
+pipe(3)
+
+
2.0
+
+
+

The power of Transform and Pipeline is best understood by seeing how they’re used to create a complete data processing pipeline. This is explained in chapter 11 of the fastai book, which is available for free in Jupyter Notebook format.

+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/transform.html b/transform.html new file mode 100644 index 00000000..6e022ca3 --- /dev/null +++ b/transform.html @@ -0,0 +1,1433 @@ + + + + + + + + + + +Transforms – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Transforms

+
+ +
+
+ Definition of Transform and Pipeline +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from __future__ import annotations
+from nbdev.showdoc import *
+from fastcore.test import *
+from fastcore.nb_imports import *
+
+

The classes here provide functionality for creating a composition of partially reversible functions. By “partially reversible” we mean that a transform can be decoded, creating a form suitable for display. This is not necessarily identical to the original form (e.g. a transform that changes a byte tensor to a float tensor does not recreate a byte tensor when decoded, since that may lose precision, and a float tensor can be displayed already).

+

Classes are also provided and for composing transforms, and mapping them over collections. Pipeline is a transform which composes several Transform, knowing how to decode them or show an encoded item.

+
+

source

+
+

Transform

+
+
 Transform (enc=None, dec=None, split_idx=None, order=None)
+
+

Delegates (__call__,decode,setup) to (encodes,decodes,setups) if split_idx matches

+

A Transform is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the Transform class provides several mechanisms that make the process of building them easy and flexible.

+
+
+

The main Transform features:

+
    +
  • Type dispatch - Type annotations are used to determine if a transform should be applied to the given argument. It also gives an option to provide several implementations and it choses the one to run based on the type. This is useful for example when running both independent and dependent variables through the pipeline where some transforms only make sense for one and not the other. Another usecase is designing a transform that handles different data formats. Note that if a transform takes multiple arguments only the type of the first one is used for dispatch.
  • +
  • Handling of tuples - When a tuple (or a subclass of tuple) of data is passed to a transform it will get applied to each element separately. You can opt out of this behavior by passing a list or an L, as only tuples gets this specific behavior. An alternative is to use ItemTransform defined below, which will always take the input as a whole.
  • +
  • Reversability - A transform can be made reversible by implementing the decodes method. This is mainly used to turn something like a category which is encoded as a number back into a label understandable by humans for showing purposes. Like the regular call method, the decode method that is used to decode will be applied over each element of a tuple separately.
  • +
  • Type propagation - Whenever possible a transform tries to return data of the same type it received. Mainly used to maintain semantics of things like ArrayImage which is a thin wrapper of pytorch’s Tensor. You can opt out of this behavior by adding ->None return type annotation.
  • +
  • Preprocessing - The setup method can be used to perform any one-time calculations to be later used by the transform, for example generating a vocabulary to encode categorical data.
  • +
  • Filtering based on the dataset type - By setting the split_idx flag you can make the transform be used only in a specific DataSource subset like in training, but not validation.
  • +
  • Ordering - You can set the order attribute which the Pipeline uses when it needs to merge two lists of transforms.
  • +
  • Appending new behavior with decorators - You can easily extend an existing Transform by creating encodes or decodes methods for new data types. You can put those new methods outside the original transform definition and decorate them with the class you wish them patched into. This can be used by the fastai library users to add their own behavior, or multiple modules contributing to the same transform.
  • +
+
+
+

Defining a Transform

+

There are a few ways to create a transform with different ratios of simplicity to flexibility. - Extending the Transform class - Use inheritence to implement the methods you want. - Passing methods to the constructor - Instantiate the Transform class and pass your functions as enc and dec arguments. - @Transform decorator - Turn any function into a Transform by just adding a decorator - very straightforward if all you need is a single encodes implementation. - Passing a function to fastai APIs - Same as above, but when passing a function to other transform aware classes like Pipeline or TfmdDS you don’t even need a decorator. Your function will get converted to a Transform automatically.

+

A simple way to create a Transform is to pass a function to the constructor. In the below example, we pass an anonymous function that does integer division by 2:

+
+
f = Transform(lambda o:o//2)
+
+

If you call this transform, it will apply the transformation:

+
+
test_eq_type(f(2), 1)
+
+

Another way to define a Transform is to extend the Transform class:

+
+
class A(Transform): pass
+
+

However, to enable your transform to do something, you have to define an encodes method. Note that we can use the class name as a decorator to add this method to the original class.

+
+
@A
+def encodes(self, x): return x+1
+
+f1 = A()
+test_eq(f1(1), 2) # f1(1) is the same as f1.encode(1)
+
+

In addition to adding an encodes method, we can also add a decodes method. This enables you to call the decode method (without an s). For more information about the purpose of decodes, see the discussion about Reversibility in the above section.

+

Just like with encodes, you can add a decodes method to the original class by using the class name as a decorator:

+
+
class B(A): pass
+
+@B
+def decodes(self, x): return x-1
+
+f2 = B()
+test_eq(f2.decode(2), 1)
+
+test_eq(f2(1), 2) # uses A's encode method from the parent class
+
+

If you do not define an encodes or decodes method the original value will be returned:

+
+
class _Tst(Transform): pass 
+
+f3 = _Tst() # no encodes or decodes method have been defined
+test_eq_type(f3.decode(2.0), 2.0)
+test_eq_type(f3(2), 2)
+
+

Transforms can be created from class methods too:

+
+
class A:
+    @classmethod
+    def create(cls, x:int): return x+1
+test_eq(Transform(A.create)(1), 2)
+
+
+

Defining Transforms With A Decorator

+

Transform can be used as a decorator to turn a function into a Transform.

+
+
@Transform
+def f(x): return x//2
+test_eq_type(f(2), 1)
+test_eq_type(f.decode(2.0), 2.0)
+
+@Transform
+def f(x): return x*2
+test_eq_type(f(2), 4)
+test_eq_type(f.decode(2.0), 2.0)
+
+
+
+

Typed Dispatch and Transforms

+

We can also apply different transformations depending on the type of the input passed by using TypedDispatch. TypedDispatch automatically works with Transform when using type hints:

+
+
class A(Transform): pass
+
+@A
+def encodes(self, x:int): return x//2
+
+@A
+def encodes(self, x:float): return x+1
+
+

When we pass in an int, this calls the first encodes method:

+
+
f = A()
+test_eq_type(f(3), 1)
+
+

When we pass in a float, this calls the second encodes method:

+
+
test_eq_type(f(2.), 3.)
+
+

When we pass in a type that is not specified in encodes, the original value is returned:

+
+
test_eq(f('a'), 'a')
+
+

If the type annotation is a tuple, then any type in the tuple will match:

+
+
class MyClass(int): pass
+
+class A(Transform):
+    def encodes(self, x:MyClass|float): return x/2
+    def encodes(self, x:str|list): return str(x)+'_1'
+
+f = A()
+
+

The below two examples match the first encodes, with a type of MyClass and float, respectively:

+
+
test_eq(f(MyClass(2)), 1.) # input is of type MyClass 
+test_eq(f(6.0), 3.0) # input is of type float
+
+

The next two examples match the second encodes method, with a type of str and list, respectively:

+
+
test_eq(f('a'), 'a_1') # input is of type str
+test_eq(f(['a','b','c']), "['a', 'b', 'c']_1") # input is of type list
+
+
+
+

Casting Types With Transform

+

Without any intervention it is easy for operations to change types in Python. For example, FloatSubclass (defined below) becomes a float after performing multiplication:

+
+
class FloatSubclass(float): pass
+test_eq_type(FloatSubclass(3.0) * 2, 6.0)
+
+

This behavior is often not desirable when performing transformations on data. Therefore, Transform will attempt to cast the output to be of the same type as the input by default. In the below example, the output will be cast to a FloatSubclass type to match the type of the input:

+
+
@Transform
+def f(x): return x*2
+
+test_eq_type(f(FloatSubclass(3.0)), FloatSubclass(6.0))
+
+

We can optionally turn off casting by annotating the transform function with a return type of None:

+
+
@Transform
+def f(x)-> None: return x*2 # Same transform as above, but with a -> None annotation
+
+test_eq_type(f(FloatSubclass(3.0)), 6.0)  # Casting is turned off because of -> None annotation
+
+

However, Transform will only cast output back to the input type when the input is a subclass of the output. In the below example, the input is of type FloatSubclass which is not a subclass of the output which is of type str. Therefore, the output doesn’t get cast back to FloatSubclass and stays as type str:

+
+
@Transform
+def f(x): return str(x)
+    
+test_eq_type(f(Float(2.)), '2.0')
+
+

Just like encodes, the decodes method will cast outputs to match the input type in the same way. In the below example, the output of decodes remains of type MySubclass:

+
+
class MySubclass(int): pass
+
+def enc(x): return MySubclass(x+1)
+def dec(x): return x-1
+
+
+f = Transform(enc,dec)
+t = f(1) # t is of type MySubclass
+test_eq_type(f.decode(t), MySubclass(1)) # the output of decode is cast to MySubclass to match the input type.
+
+
+
+

Apply Transforms On Subsets With split_idx

+

You can apply transformations to subsets of data by specifying a split_idx property. If a transform has a split_idx then it’s only applied if the split_idx param matches. In the below example, we set split_idx equal to 1:

+
+
def enc(x): return x+1
+def dec(x): return x-1
+f = Transform(enc,dec)
+f.split_idx = 1
+
+

The transformations are applied when a matching split_idx parameter is passed:

+
+
test_eq(f(1, split_idx=1),2)
+test_eq(f.decode(2, split_idx=1),1)
+
+

On the other hand, transformations are ignored when the split_idx parameter does not match:

+
+
test_eq(f(1, split_idx=0), 1)
+test_eq(f.decode(2, split_idx=0), 2)
+
+
+
+

Transforms on Lists

+

Transform operates on lists as a whole, not element-wise:

+
+
class A(Transform):
+    def encodes(self, x): return dict(x)
+    def decodes(self, x): return list(x.items())
+    
+f = A()
+_inp = [(1,2), (3,4)]
+t = f(_inp)
+
+test_eq(t, dict(_inp))
+test_eq(f.decodes(t), _inp)
+
+

If you want a transform to operate on a list elementwise, you must implement this appropriately in the encodes and decodes methods:

+
+
class AL(Transform): pass
+
+@AL
+def encodes(self, x): return [x_+1 for x_ in x]
+
+@AL
+def decodes(self, x): return [x_-1 for x_ in x]
+
+f = AL()
+t = f([1,2])
+
+test_eq(t, [2,3])
+test_eq(f.decode(t), [1,2])
+
+
+
+

Transforms on Tuples

+

Unlike lists, Transform operates on tuples element-wise.

+
+
def neg_int(x): return -x
+f = Transform(neg_int)
+
+test_eq(f((1,2,3)), (-1,-2,-3))
+
+

Transforms will also apply TypedDispatch element-wise on tuples when an input type annotation is specified. In the below example, the values 1.0 and 3.0 are ignored because they are of type float, not int:

+
+
def neg_int(x:int): return -x
+f = Transform(neg_int)
+
+test_eq(f((1.0, 2, 3.0)), (1.0, -2, 3.0))
+
+

Another example of how Transform can use TypedDispatch with tuples is shown below:

+
+
class B(Transform): pass
+
+@B
+def encodes(self, x:int): return x+1
+
+@B
+def encodes(self, x:str): return x+'hello'
+
+@B
+def encodes(self, x): return str(x)+'!'
+
+

If the input is not an int or str, the third encodes method will apply:

+
+
b = B()
+test_eq(b([1]), '[1]!') 
+test_eq(b([1.0]), '[1.0]!')
+
+

However, if the input is a tuple, then the appropriate method will apply according to the type of each element in the tuple:

+
+
test_eq(b(('1',)), ('1hello',))
+test_eq(b((1,2)), (2,3))
+test_eq(b(('a',1.0)), ('ahello','1.0!'))
+
+

Dispatching over tuples works recursively, by the way:

+
+
class B(Transform):
+    def encodes(self, x:int): return x+1
+    def encodes(self, x:str): return x+'_hello'
+    def decodes(self, x:int): return x-1
+    def decodes(self, x:str): return x.replace('_hello', '')
+
+f = B()
+start = (1.,(2,'3'))
+t = f(start)
+test_eq_type(t, (1.,(3,'3_hello')))
+test_eq(f.decode(t), start)
+
+

Dispatching also works with typing module type classes, like numbers.integral:

+
+
@Transform
+def f(x:numbers.Integral): return x+1
+
+t = f((1,'1',1))
+test_eq(t, (2, '1', 2))
+
+
+

source

+
+
+
+

InplaceTransform

+
+
 InplaceTransform (enc=None, dec=None, split_idx=None, order=None)
+
+

A Transform that modifies in-place and just returns whatever it’s passed

+
+
class A(InplaceTransform): pass
+
+@A
+def encodes(self, x:pd.Series): x.fillna(10, inplace=True)
+    
+f = A()
+
+test_eq_type(f(pd.Series([1,2,None])),pd.Series([1,2,10],dtype=np.float64)) #fillna fills with floats.
+
+
+

source

+
+
+

DisplayedTransform

+
+
 DisplayedTransform (enc=None, dec=None, split_idx=None, order=None)
+
+

A transform with a __repr__ that shows its attrs

+

Transforms normally are represented by just their class name and a list of encodes and decodes implementations:

+
+
class A(Transform): encodes,decodes = noop,noop
+f = A()
+f
+
+
A:
+encodes: (object,object) -> noop
+decodes: (object,object) -> noop
+
+
+

A DisplayedTransform will in addition show the contents of all attributes listed in the comma-delimited string self.store_attrs:

+
+
class A(DisplayedTransform):
+    encodes = noop
+    def __init__(self, a, b=2):
+        super().__init__()
+        store_attr()
+    
+A(a=1,b=2)
+
+
A -- {'a': 1, 'b': 2}:
+encodes: (object,object) -> noop
+decodes: 
+
+
+
+

source

+
+
+

ItemTransform

+
+
 ItemTransform (enc=None, dec=None, split_idx=None, order=None)
+
+

A transform that always take tuples as items

+

ItemTransform is the class to use to opt out of the default behavior of Transform.

+
+
class AIT(ItemTransform): 
+    def encodes(self, xy): x,y=xy; return (x+y,y)
+    def decodes(self, xy): x,y=xy; return (x-y,y)
+    
+f = AIT()
+test_eq(f((1,2)), (3,2))
+test_eq(f.decode((3,2)), (1,2))
+
+

If you pass a special tuple subclass, the usual retain type behavior of Transform will keep it:

+
+
class _T(tuple): pass
+x = _T((1,2))
+test_eq_type(f(x), _T((3,2)))
+
+
+

source

+
+
+

get_func

+
+
 get_func (t, name, *args, **kwargs)
+
+

Get the t.name (potentially partial-ized with args and kwargs) or noop if not defined

+

This works for any kind of t supporting getattr, so a class or a module.

+
+
test_eq(get_func(operator, 'neg', 2)(), -2)
+test_eq(get_func(operator.neg, '__call__')(2), -2)
+test_eq(get_func(list, 'foobar')([2]), [2])
+a = [2,1]
+get_func(list, 'sort')(a)
+test_eq(a, [1,2])
+
+

Transforms are built with multiple-dispatch: a given function can have several methods depending on the type of the object received. This is done directly with the TypeDispatch module and type-annotation in Transform, but you can also use the following class.

+
+

source

+
+
+

Func

+
+
 Func (name, *args, **kwargs)
+
+

Basic wrapper around a name with args and kwargs to call on a given type

+

You can call the Func object on any module name or type, even a list of types. It will return the corresponding function (with a default to noop if nothing is found) or list of functions.

+
+
test_eq(Func('sqrt')(math), math.sqrt)
+
+
+
+
+

Sig

+
+
 Sig (*args, **kwargs)
+
+

Sig is just sugar-syntax to create a Func object more easily with the syntax Sig.name(*args, **kwargs).

+
+
f = Sig.sqrt()
+test_eq(f(math), math.sqrt)
+
+
+

source

+
+
+

compose_tfms

+
+
 compose_tfms (x, tfms, is_enc=True, reverse=False, **kwargs)
+
+

Apply all func_nm attribute of tfms on x, maybe in reverse order

+
+
def to_int  (x):   return Int(x)
+def to_float(x):   return Float(x)
+def double  (x):   return x*2
+def half(x)->None: return x/2
+
+
+
def test_compose(a, b, *fs): test_eq_type(compose_tfms(a, tfms=map(Transform,fs)), b)
+
+test_compose(1,   Int(1),   to_int)
+test_compose(1,   Float(1), to_int,to_float)
+test_compose(1,   Float(2), to_int,to_float,double)
+test_compose(2.0, 2.0,      to_int,double,half)
+
+
+
class A(Transform):
+    def encodes(self, x:float):  return Float(x+1)
+    def decodes(self, x): return x-1
+    
+tfms = [A(), Transform(math.sqrt)]
+t = compose_tfms(3., tfms=tfms)
+test_eq_type(t, Float(2.))
+test_eq(compose_tfms(t, tfms=tfms, is_enc=False), 1.)
+test_eq(compose_tfms(4., tfms=tfms, reverse=True), 3.)
+
+
+
tfms = [A(), Transform(math.sqrt)]
+test_eq(compose_tfms((9,3.), tfms=tfms), (3,2.))
+
+
+

source

+
+
+

mk_transform

+
+
 mk_transform (f)
+
+

Convert function f to Transform if it isn’t already one

+
+

source

+
+
+

gather_attrs

+
+
 gather_attrs (o, k, nm)
+
+

Used in getattr to collect all attrs k from self.{nm}

+
+

source

+
+
+

gather_attr_names

+
+
 gather_attr_names (o, nm)
+
+

Used in dir to collect all attrs k from self.{nm}

+
+

source

+
+
+

Pipeline

+
+
 Pipeline (funcs=None, split_idx=None)
+
+

A pipeline of composed (for encode/decode) transforms, setup with types

+
+
add_docs(Pipeline,
+         __call__="Compose `__call__` of all `fs` on `o`",
+         decode="Compose `decode` of all `fs` on `o`",
+         show="Show `o`, a single item from a tuple, decoding as needed",
+         add="Add transforms `ts`",
+         setup="Call each tfm's `setup` in order")
+
+

Pipeline is a wrapper for compose_tfms. You can pass instances of Transform or regular functions in funcs, the Pipeline will wrap them all in Transform (and instantiate them if needed) during the initialization. It handles the transform setup by adding them one at a time and calling setup on each, goes through them in order in __call__ or decode and can show an object by applying decoding the transforms up until the point it gets an object that knows how to show itself.

+
+
# Empty pipeline is noop
+pipe = Pipeline()
+test_eq(pipe(1), 1)
+test_eq(pipe((1,)), (1,))
+# Check pickle works
+assert pickle.loads(pickle.dumps(pipe))
+
+
+
class IntFloatTfm(Transform):
+    def encodes(self, x):  return Int(x)
+    def decodes(self, x):  return Float(x)
+    foo=1
+
+int_tfm=IntFloatTfm()
+
+def neg(x): return -x
+neg_tfm = Transform(neg, neg)
+
+
+
pipe = Pipeline([neg_tfm, int_tfm])
+
+start = 2.0
+t = pipe(start)
+test_eq_type(t, Int(-2))
+test_eq_type(pipe.decode(t), Float(start))
+test_stdout(lambda:pipe.show(t), '-2')
+
+
+
pipe = Pipeline([neg_tfm, int_tfm])
+t = pipe(start)
+test_stdout(lambda:pipe.show(pipe((1.,2.))), '-1\n-2')
+test_eq(pipe.foo, 1)
+assert 'foo' in dir(pipe)
+assert 'int_float_tfm' in dir(pipe)
+
+

You can add a single transform or multiple transforms ts using Pipeline.add. Transforms will be ordered by Transform.order.

+
+
pipe = Pipeline([neg_tfm, int_tfm])
+class SqrtTfm(Transform):
+    order=-1
+    def encodes(self, x): 
+        return x**(.5)
+    def decodes(self, x): return x**2
+pipe.add(SqrtTfm())
+test_eq(pipe(4),-2)
+test_eq(pipe.decode(-2),4)
+pipe.add([SqrtTfm(),SqrtTfm()])
+test_eq(pipe(256),-2)
+test_eq(pipe.decode(-2),256)
+
+

Transforms are available as attributes named with the snake_case version of the names of their types. Attributes in transforms can be directly accessed as attributes of the pipeline.

+
+
test_eq(pipe.int_float_tfm, int_tfm)
+test_eq(pipe.foo, 1)
+
+pipe = Pipeline([int_tfm, int_tfm])
+pipe.int_float_tfm
+test_eq(pipe.int_float_tfm[0], int_tfm)
+test_eq(pipe.foo, [1,1])
+
+
+
# Check opposite order
+pipe = Pipeline([int_tfm,neg_tfm])
+t = pipe(start)
+test_eq(t, -2)
+test_stdout(lambda:pipe.show(t), '-2')
+
+
+
class A(Transform):
+    def encodes(self, x):  return int(x)
+    def decodes(self, x):  return Float(x)
+
+pipe = Pipeline([neg_tfm, A])
+t = pipe(start)
+test_eq_type(t, -2)
+test_eq_type(pipe.decode(t), Float(start))
+test_stdout(lambda:pipe.show(t), '-2.0')
+
+
+
s2 = (1,2)
+pipe = Pipeline([neg_tfm, A])
+t = pipe(s2)
+test_eq_type(t, (-1,-2))
+test_eq_type(pipe.decode(t), (Float(1.),Float(2.)))
+test_stdout(lambda:pipe.show(t), '-1.0\n-2.0')
+
+
+
from PIL import Image
+
+
+
class ArrayImage(ndarray):
+    _show_args = {'cmap':'viridis'}
+    def __new__(cls, x, *args, **kwargs):
+        if isinstance(x,tuple): super().__new__(cls, x, *args, **kwargs)
+        if args or kwargs: raise RuntimeError('Unknown array init args')
+        if not isinstance(x,ndarray): x = array(x)
+        return x.view(cls)
+    
+    def show(self, ctx=None, figsize=None, **kwargs):
+        if ctx is None: _,ctx = plt.subplots(figsize=figsize)
+        ctx.imshow(im, **{**self._show_args, **kwargs})
+        ctx.axis('off')
+        return ctx
+    
+im = Image.open(TEST_IMAGE)
+im_t = ArrayImage(im)
+
+
+
def f1(x:ArrayImage): return -x
+def f2(x): return Image.open(x).resize((128,128))
+def f3(x:Image.Image): return(ArrayImage(array(x)))
+
+
+
pipe = Pipeline([f2,f3,f1])
+t = pipe(TEST_IMAGE)
+test_eq(type(t), ArrayImage)
+test_eq(t, -array(f3(f2(TEST_IMAGE))))
+
+
+
pipe = Pipeline([f2,f3])
+t = pipe(TEST_IMAGE)
+ax = pipe.show(t)
+
+
+
+

+
+
+
+
+
+
#test_fig_exists(ax)
+
+
+
#Check filtering is properly applied
+add1 = B()
+add1.split_idx = 1
+pipe = Pipeline([neg_tfm, A(), add1])
+test_eq(pipe(start), -2)
+pipe.split_idx=1
+test_eq(pipe(start), -1)
+pipe.split_idx=0
+test_eq(pipe(start), -2)
+for t in [None, 0, 1]:
+    pipe.split_idx=t
+    test_eq(pipe.decode(pipe(start)), start)
+    test_stdout(lambda: pipe.show(pipe(start)), "-2.0")
+
+
+
def neg(x): return -x
+test_eq(type(mk_transform(neg)), Transform)
+test_eq(type(mk_transform(math.sqrt)), Transform)
+test_eq(type(mk_transform(lambda a:a*2)), Transform)
+test_eq(type(mk_transform(Pipeline([neg]))), Pipeline)
+
+
+
+

Methods

+
+
#TODO: method examples
+
+
+

source

+
+
+

Pipeline.__call__

+
+
 Pipeline.__call__ (o)
+
+

Call self as a function.

+
+

source

+
+
+

Pipeline.decode

+
+
 Pipeline.decode (o, full=True)
+
+
+

source

+
+
+

Pipeline.setup

+
+
 Pipeline.setup (items=None, train_setup=False)
+
+

During the setup, the Pipeline starts with no transform and adds them one at a time, so that during its setup, each transform gets the items processed up to its point and not after.

+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/xdg.html b/xdg.html new file mode 100644 index 00000000..46f1ee4e --- /dev/null +++ b/xdg.html @@ -0,0 +1,850 @@ + + + + + + + + + + +XDG – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

XDG

+
+ +
+
+ XDG Base Directory Specification helpers. +
+
+ + +
+ + + + +
+ + + +
+ + + +

See the XDG Base Directory Specification for more information.

+
+

Overview

+

xdg_cache_home, xdg_config_home, xdg_data_home, and xdg_state_home return pathlib.Path objects containing the value of the environment variable named XDG_CACHE_HOME, XDG_CONFIG_HOME, XDG_DATA_HOME, and XDG_STATE_HOME respectively, or the default defined in the specification if the environment variable is unset, empty, or contains a relative path rather than absolute path.

+

xdg_config_dirs and xdg_data_dirs return a list of pathlib.Path objects containing the value, split on colons, of the environment variable named XDG_CONFIG_DIRS and XDG_DATA_DIRS respectively, or the default defined in the specification if the environment variable is unset or empty. Relative paths are ignored, as per the specification.

+

xdg_runtime_dir returns a pathlib.Path object containing the value of the XDG_RUNTIME_DIR environment variable, or None if the environment variable is not set, or contains a relative path rather than absolute path.

+
+
+

Helpers

+

We’ll start by defining a context manager that temporarily sets an environment variable to demonstrate the behaviour of each helper function:

+
+
from contextlib import contextmanager
+
+
+
@contextmanager
+def env(variable, value):
+    old = os.environ.get(variable, None)
+    try:
+        os.environ[variable] = value
+        yield
+    finally:
+        if old is None: del os.environ[variable]
+        else: os.environ[variable] = old
+
+
+

source

+
+

xdg_cache_home

+
+
 xdg_cache_home ()
+
+

Path corresponding to XDG_CACHE_HOME

+
+
from fastcore.test import *
+
+
+
test_eq(xdg_cache_home(), Path.home()/'.cache')
+with env('XDG_CACHE_HOME', '/home/fastai/.cache'):
+    test_eq(xdg_cache_home(), Path('/home/fastai/.cache'))
+
+
+

source

+
+
+

xdg_config_dirs

+
+
 xdg_config_dirs ()
+
+

Paths corresponding to XDG_CONFIG_DIRS

+
+
test_eq(xdg_config_dirs(), [Path('/etc/xdg')])
+with env('XDG_CONFIG_DIRS', '/home/fastai/.xdg:/home/fastai/.config'):
+    test_eq(xdg_config_dirs(), [Path('/home/fastai/.xdg'), Path('/home/fastai/.config')])
+
+
+

source

+
+
+

xdg_config_home

+
+
 xdg_config_home ()
+
+

Path corresponding to XDG_CONFIG_HOME

+
+
test_eq(xdg_config_home(), Path.home()/'.config')
+with env('XDG_CONFIG_HOME', '/home/fastai/.config'):
+    test_eq(xdg_config_home(), Path('/home/fastai/.config'))
+
+
+

source

+
+
+

xdg_data_dirs

+
+
 xdg_data_dirs ()
+
+

Paths corresponding to XDG_DATA_DIRS`

+
+

source

+
+
+

xdg_data_home

+
+
 xdg_data_home ()
+
+

Path corresponding to XDG_DATA_HOME

+
+
test_eq(xdg_data_home(), Path.home()/'.local/share')
+with env('XDG_DATA_HOME', '/home/fastai/.data'):
+    test_eq(xdg_data_home(), Path('/home/fastai/.data'))
+
+
+

source

+
+
+

xdg_runtime_dir

+
+
 xdg_runtime_dir ()
+
+

Path corresponding to XDG_RUNTIME_DIR

+
+

source

+
+
+

xdg_state_home

+
+
 xdg_state_home ()
+
+

Path corresponding to XDG_STATE_HOME

+
+
test_eq(xdg_state_home(), Path.home()/'.local/state')
+with env('XDG_STATE_HOME', '/home/fastai/.state'):
+    test_eq(xdg_state_home(), Path('/home/fastai/.state'))
+
+
+

Copyright © 2016-2021 Scott Stevenson

+

Modifications copyright © 2022 onwards Jeremy Howard

+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/xml.html b/xml.html new file mode 100644 index 00000000..7096c03c --- /dev/null +++ b/xml.html @@ -0,0 +1,962 @@ + + + + + + + + + + +XML – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

XML

+
+ +
+
+ Concise generation of XML. +
+
+ + +
+ + + + +
+ + + +
+ + + +
+
from IPython.display import Markdown
+from pprint import pprint
+
+
+

source

+
+

FT

+
+
 FT (tag:str, cs:tuple, attrs:dict=None, void_=False, **kwargs)
+
+

A ‘Fast Tag’ structure, containing tag,children,and attrs

+
+

source

+
+
+

attrmap

+
+
 attrmap (o)
+
+
+

source

+
+
+

valmap

+
+
 valmap (o)
+
+
+

source

+
+
+

ft

+
+
 ft (tag:str, *c, void_:bool=False, attrmap:<built-
+     infunctioncallable>=<function attrmap>, valmap:<built-
+     infunctioncallable>=<function valmap>, **kw)
+
+

Create an FT structure for to_xml()

+
+
a = Body(Div('hi', a=1, b=True, cls=()), P('hi', cls=['a',1], style=dict(a=1,b=2)))
+a
+
+
body((div(('hi',),{'a': 1, 'b': True, 'class': None}), p(('hi',),{'class': 'a 1', 'style': 'a:1; b:2'})),{})
+
+
+

The main HTML tags are exported as ft partials.

+

Attributes are passed as keywords. Use ‘klass’ and ‘fr’ instead of ‘class’ and ‘for’, to avoid Python reserved word clashes.

+
+

source

+
+
+

Html

+
+
 Html (*c, doctype=True, **kwargs)
+
+

An HTML tag, optionally preceeded by !DOCTYPE HTML

+
+
samp = Html(
+    Head(Title('Some page')),
+    Body(Div('Some text\nanother line', (Input(name="jph's"), Img(src="filename", data=1)),
+             cls=['myclass', 'another'],
+             style={'padding':1, 'margin':2}))
+)
+pprint(samp)
+
+
(!doctype((),{'html': True}),
+ html((head((title(('Some page',),{}),),{}), body((div(('Some text\nanother line', input((),{'name': "jph's"}), img((),{'src': 'filename', 'data': 1})),{'class': 'myclass another', 'style': 'padding:1; margin:2'}),),{})),{}))
+
+
+

The three elements of the list can also be accessed with property names, so you don’t have to remember their order.

+
+
elem = P('Some text', id="myid")
+print(elem.tag)
+print(elem.children)
+print(elem.attrs)
+
+
p
+('Some text',)
+{'id': 'myid'}
+
+
+

You can also get and set attrs directly:

+
+
elem.id = 'newid'
+print(elem.id, elem.get('id'), elem.get('foo', 'missing'))
+elem
+
+
newid newid missing
+
+
+
p(('Some text',),{'id': 'newid'})
+
+
+
+

source

+
+
+

Safe

+

*str(object=’’) -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

+

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.__str__() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to ‘strict’.*

+
+

source

+
+
+

to_xml

+
+
 to_xml (elm, lvl=0, indent:bool=True)
+
+

Convert ft element tree into an XML string

+
+
h = to_xml(samp)
+print(h)
+
+
<!doctype html>
+
+<html>
+  <head><title>Some page</title>
+</head>
+  <body><div class="myclass another" style="padding:1; margin:2">
+Some text
+another line
+  <input name="jph's">
+  <img src="filename" data="1">
+</div>
+</body>
+</html>
+
+
+
+
+
class PageTitle:
+    def __ft__(self): return H1("Hello")
+
+class HomePage:
+    def __ft__(self): return Div(PageTitle(), Div('hello'))
+
+h = to_xml(Div(HomePage()))
+expected_output = """<div>
+  <div>
+    <h1>Hello</h1>
+    <div>hello</div>
+  </div>
+</div>
+"""
+assert h == expected_output
+
+
+
h = to_xml(samp, indent=False)
+print(h)
+
+
<!doctype html><html><head><title>Some page</title>
+</head><body><div class="myclass another" style="padding:1; margin:2">
+Some text
+another line
+  <input name="jph's">
+  <img src="filename" data="1">
+</div>
+</body></html>
+
+
+

Interoperability both directions with Django and Jinja using the html() protocol:

+
+
def _esc(s): return s.__html__() if hasattr(s, '__html__') else Safe(escape(s))
+
+r = Safe('<b>Hello from Django</b>')
+print(to_xml(Div(r)))
+print(_esc(Div(P('Hello from fastcore <3'))))
+
+
<div><b>Hello from Django</b></div>
+
+<div><p>Hello from fastcore &lt;3</p>
+</div>
+
+
+
+
+

source

+
+
+

highlight

+
+
 highlight (s, lang='html')
+
+

Markdown to syntax-highlight s in language lang

+
+

source

+
+
+

showtags

+
+
 showtags (s)
+
+
+

source

+
+
+

getattr

+
+
 __getattr__ (tag)
+
+
+

source

+
+
+

FT.__call__

+
+
 FT.__call__ (*c, **kw)
+
+

Call self as a function.

+

You can also reorder the children to come after the attrs, if you use this alternative syntax for FT where the children are in a second pair of () (behind the scenes this is because FT implements __call__ to add children).

+
+
Body(klass='myclass')(
+    Div(style='padding:3px')(
+        'Some text ',
+        I(spurious=True)('in italics'),
+        Input(name='me'),
+        Img(src="filename", data=1)
+    )
+)
+
+
<body class="myclass"><div style="padding:3px">
+Some text 
+  <i spurious>in italics</i>
+  <input name="me">
+  <img src="filename" data="1">
+</div>
+</body>
+
+
+ + +
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/xtras.html b/xtras.html new file mode 100644 index 00000000..241edf92 --- /dev/null +++ b/xtras.html @@ -0,0 +1,2245 @@ + + + + + + + + + + +Utility functions – fastcore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

Utility functions

+
+ +
+
+ Utility functions used in the fastai library +
+
+ + +
+ + + + +
+ + + +
+ + + +
+

File Functions

+

Utilities (other than extensions to Pathlib.Path) for dealing with IO.

+
+

source

+
+

walk

+
+
 walk (path:pathlib.Path|str, symlinks:bool=True, keep_file:<built-
+       infunctioncallable>=<function ret_true>, keep_folder:<built-
+       infunctioncallable>=<function ret_true>, skip_folder:<built-
+       infunctioncallable>=<function ret_false>, func:<built-
+       infunctioncallable>=<function join>, ret_folders:bool=False)
+
+

Generator version of os.walk, using functions to filter files and folders

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
pathPath | strpath to start searching
symlinksboolTruefollow symlinks?
keep_filecallableret_truefunction that returns True for wanted files
keep_foldercallableret_truefunction that returns True for folders to enter
skip_foldercallableret_falsefunction that returns True for folders to skip
funccallablejoinfunction to apply to each matched file
ret_foldersboolFalsereturn folders, not just files
+
+

source

+
+
+

globtastic

+
+
 globtastic (path:pathlib.Path|str, recursive:bool=True,
+             symlinks:bool=True, file_glob:str=None, file_re:str=None,
+             folder_re:str=None, skip_file_glob:str=None,
+             skip_file_re:str=None, skip_folder_re:str=None, func:<built-
+             infunctioncallable>=<function join>, ret_folders:bool=False)
+
+

A more powerful glob, including regex matches, symlink handling, and skip parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
pathPath | strpath to start searching
recursiveboolTruesearch subfolders
symlinksboolTruefollow symlinks?
file_globstrNoneOnly include files matching glob
file_restrNoneOnly include files matching regex
folder_restrNoneOnly enter folders matching regex
skip_file_globstrNoneSkip files matching glob
skip_file_restrNoneSkip files matching regex
skip_folder_restrNoneSkip folders matching regex,
funccallablejoinfunction to apply to each matched file
ret_foldersboolFalsereturn folders, not just files
ReturnsLPaths to matched files
+
+
globtastic('.', skip_folder_re='^[_.]', folder_re='core', file_glob='*.*py*', file_re='c')
+
+
(#5) ['./fastcore/docments.py','./fastcore/dispatch.py','./fastcore/basics.py','./fastcore/docscrape.py','./fastcore/script.py']
+
+
+
+

source

+
+
+

maybe_open

+
+
 maybe_open (f, mode='r', **kwargs)
+
+

Context manager: open f if it is a path (and close on exit)

+

This is useful for functions where you want to accept a path or file. maybe_open will not close your file handle if you pass one in.

+
+
def _f(fn):
+    with maybe_open(fn) as f: return f.encoding
+
+fname = '00_test.ipynb'
+sys_encoding = 'cp1252' if sys.platform == 'win32' else 'UTF-8'
+test_eq(_f(fname), sys_encoding)
+with open(fname) as fh: test_eq(_f(fh), sys_encoding)
+
+

For example, we can use this to reimplement imghdr.what from the Python standard library, which is written in Python 3.9 as:

+
+
from fastcore import imghdr
+
+
+
def what(file, h=None):
+    f = None
+    try:
+        if h is None:
+            if isinstance(file, (str,os.PathLike)):
+                f = open(file, 'rb')
+                h = f.read(32)
+            else:
+                location = file.tell()
+                h = file.read(32)
+                file.seek(location)
+        for tf in imghdr.tests:
+            res = tf(h, f)
+            if res: return res
+    finally:
+        if f: f.close()
+    return None
+
+

Here’s an example of the use of this function:

+
+
fname = 'images/puppy.jpg'
+what(fname)
+
+
'jpeg'
+
+
+

With maybe_open, Self, and L.map_first, we can rewrite this in a much more concise and (in our opinion) clear way:

+
+
def what(file, h=None):
+    if h is None:
+        with maybe_open(file, 'rb') as f: h = f.peek(32)
+    return L(imghdr.tests).map_first(Self(h,file))
+
+

…and we can check that it still works:

+
+
test_eq(what(fname), 'jpeg')
+
+

…along with the version passing a file handle:

+
+
with open(fname,'rb') as f: test_eq(what(f), 'jpeg')
+
+

…along with the h parameter version:

+
+
with open(fname,'rb') as f: test_eq(what(None, h=f.read(32)), 'jpeg')
+
+
+

source

+
+
+

mkdir

+
+
 mkdir (path, exist_ok=False, parents=False, overwrite=False, **kwargs)
+
+

Creates and returns a directory defined by path, optionally removing previous existing directory if overwrite is True

+
+
with tempfile.TemporaryDirectory() as d:
+    path = Path(os.path.join(d, 'new_dir'))
+    new_dir = mkdir(path)
+    assert new_dir.exists()
+    test_eq(new_dir, path)
+        
+    # test overwrite
+    with open(new_dir/'test.txt', 'w') as f: f.writelines('test')
+    test_eq(len(list(walk(new_dir))), 1) # assert file is present
+    new_dir = mkdir(new_dir, overwrite=True)
+    test_eq(len(list(walk(new_dir))), 0) # assert file was deleted
+
+
+

source

+
+
+

image_size

+
+
 image_size (fn)
+
+

Tuple of (w,h) for png, gif, or jpg; None otherwise

+
+
test_eq(image_size(fname), (1200,803))
+
+
+

source

+
+
+

bunzip

+
+
 bunzip (fn)
+
+

bunzip fn, raising exception if output already exists

+
+
f = Path('files/test.txt')
+if f.exists(): f.unlink()
+bunzip('files/test.txt.bz2')
+t = f.open().readlines()
+test_eq(len(t),1)
+test_eq(t[0], 'test\n')
+f.unlink()
+
+
+

source

+
+
+

loads

+
+
 loads (s, **kw)
+
+

Same as json.loads, but handles None

+
+

source

+
+
+

loads_multi

+
+
 loads_multi (s:str)
+
+

Generator of >=0 decoded json dicts, possibly with non-json ignored text at start and end

+
+
tst = """
+# ignored
+{ "a":1 }
+hello
+{
+"b":2
+}
+"""
+
+test_eq(list(loads_multi(tst)), [{'a': 1}, {'b': 2}])
+
+
+

source

+
+
+

dumps

+
+
 dumps (obj, **kw)
+
+

Same as json.dumps, but uses ujson if available

+
+

source

+
+
+

untar_dir

+
+
 untar_dir (fname, dest, rename=False, overwrite=False)
+
+

untar file into dest, creating a directory if the root contains more than one item

+
+
def test_untar(foldername, rename=False, **kwargs):
+    with tempfile.TemporaryDirectory() as d:
+        nm = os.path.join(d, 'a')
+        shutil.make_archive(nm, 'gztar', **kwargs)
+        with tempfile.TemporaryDirectory() as d2:
+            d2 = Path(d2)
+            untar_dir(nm+'.tar.gz', d2, rename=rename)
+            test_eq(d2.ls(), [d2/foldername])
+
+

If the contents of fname contain just one file or directory, it is placed directly in dest:

+
+
# using `base_dir` in `make_archive` results in `images` directory included in file names
+test_untar('images', base_dir='images')
+
+

If rename then the directory created is named based on the archive, without extension:

+
+
test_untar('a', base_dir='images', rename=True)
+
+

If the contents of fname contain multiple files and directories, a new folder in dest is created with the same name as fname (but without extension):

+
+
# using `root_dir` in `make_archive` results in `images` directory *not* included in file names
+test_untar('a', root_dir='images')
+
+
+

source

+
+
+

repo_details

+
+
 repo_details (url)
+
+

Tuple of owner,name from ssh or https git repo url

+
+
test_eq(repo_details('https://github.com/fastai/fastai.git'), ['fastai', 'fastai'])
+test_eq(repo_details('git@github.com:fastai/nbdev.git\n'), ['fastai', 'nbdev'])
+
+
+

source

+
+
+

run

+
+
 run (cmd, *rest, same_in_win=False, ignore_ex=False, as_bytes=False,
+      stderr=False)
+
+

Pass cmd (splitting with shlex if string) to subprocess.run; return stdout; raise IOError if fails

+

You can pass a string (which will be split based on standard shell rules), a list, or pass args directly:

+
+
run('echo', same_in_win=True)
+run('pip', '--version', same_in_win=True)
+run(['pip', '--version'], same_in_win=True)
+
+
'pip 23.3.1 from /Users/jhoward/miniconda3/lib/python3.11/site-packages/pip (python 3.11)'
+
+
+
+
if sys.platform == 'win32':
+    assert 'ipynb' in run('cmd /c dir /p')
+    assert 'ipynb' in run(['cmd', '/c', 'dir', '/p'])
+    assert 'ipynb' in run('cmd', '/c', 'dir',  '/p')
+else:
+    assert 'ipynb' in run('ls -ls')
+    assert 'ipynb' in run(['ls', '-l'])
+    assert 'ipynb' in run('ls', '-l')
+
+

Some commands fail in non-error situations, like grep. Use ignore_ex in those cases, which will return a tuple of stdout and returncode:

+
+
if sys.platform == 'win32':
+    test_eq(run('cmd /c findstr asdfds 00_test.ipynb', ignore_ex=True)[0], 1)
+else:
+    test_eq(run('grep asdfds 00_test.ipynb', ignore_ex=True)[0], 1)
+
+

run automatically decodes returned bytes to a str. Use as_bytes to skip that:

+
+
if sys.platform == 'win32':
+    test_eq(run('cmd /c echo hi'), 'hi')
+else:
+    test_eq(run('echo hi', as_bytes=True), b'hi\n')
+
+
+

source

+
+
+

open_file

+
+
 open_file (fn, mode='r', **kwargs)
+
+

Open a file, with optional compression if gz or bz2 suffix

+
+

source

+
+
+

save_pickle

+
+
 save_pickle (fn, o)
+
+

Save a pickle file, to a file name or opened file

+
+

source

+
+
+

load_pickle

+
+
 load_pickle (fn)
+
+

Load a pickle file from a file name or opened file

+
+
for suf in '.pkl','.bz2','.gz':
+    # delete=False is added for Windows
+    # https://stackoverflow.com/questions/23212435/permission-denied-to-write-to-my-temporary-file
+    with tempfile.NamedTemporaryFile(suffix=suf, delete=False) as f:
+        fn = Path(f.name)
+        save_pickle(fn, 't')
+        t = load_pickle(fn)
+    f.close()
+    test_eq(t,'t')
+
+
+

source

+
+
+

parse_env

+
+
 parse_env (s:str=None, fn:Union[str,pathlib.Path]=None)
+
+

Parse a shell-style environment string or file

+
+
testf = """# comment
+   # another comment
+ export FOO="bar#baz"
+BAR=thing # comment "ok"
+  baz='thong'
+QUX=quux
+export ZAP = "zip" # more comments
+   FOOBAR = 42   # trailing space and comment"""
+
+exp = dict(FOO='bar#baz', BAR='thing', baz='thong', QUX='quux', ZAP='zip', FOOBAR='42')
+
+test_eq(parse_env(testf),  exp)
+
+
+

source

+
+
+

expand_wildcards

+
+
 expand_wildcards (code)
+
+

Expand all wildcard imports in the given code string.

+
+
inp = """from math import *
+from os import *
+from random import *
+def func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)"""
+
+exp = """from math import pi, sin
+from os import path
+from random import randint
+def func(): return sin(pi) + path.join('a', 'b') + randint(1, 10)"""
+
+test_eq(expand_wildcards(inp), exp)
+
+inp = """from itertools import *
+def func(): pass"""
+test_eq(expand_wildcards(inp), inp)
+
+inp = """def outer():
+    from math import *
+    def inner():
+        from os import *
+        return sin(pi) + path.join('a', 'b')"""
+
+exp = """def outer():
+    from math import pi, sin
+    def inner():
+        from os import path
+        return sin(pi) + path.join('a', 'b')"""
+
+test_eq(expand_wildcards(inp), exp)
+
+
+
+
+

Collections

+
+

source

+
+

dict2obj

+
+
 dict2obj (d, list_func=<class 'fastcore.foundation.L'>, dict_func=<class
+           'fastcore.basics.AttrDict'>)
+
+

Convert (possibly nested) dicts (or lists of dicts) to AttrDict

+

This is a convenience to give you “dotted” access to (possibly nested) dictionaries, e.g:

+
+
d1 = dict(a=1, b=dict(c=2,d=3))
+d2 = dict2obj(d1)
+test_eq(d2.b.c, 2)
+test_eq(d2.b['c'], 2)
+
+

It can also be used on lists of dicts.

+
+
_list_of_dicts = [d1, d1]
+ds = dict2obj(_list_of_dicts)
+test_eq(ds[0].b.c, 2)
+
+
+

source

+
+
+

obj2dict

+
+
 obj2dict (d)
+
+

Convert (possibly nested) AttrDicts (or lists of AttrDicts) to dict

+

obj2dict can be used to reverse what is done by dict2obj:

+
+
test_eq(obj2dict(d2), d1)
+test_eq(obj2dict(ds), _list_of_dicts)
+
+
+

source

+
+
+

repr_dict

+
+
 repr_dict (d)
+
+

Print nested dicts and lists, such as returned by dict2obj

+
+
print(repr_dict(d2))
+
+
- a: 1
+- b: 
+  - c: 2
+  - d: 3
+
+
+
+

source

+
+
+

is_listy

+
+
 is_listy (x)
+
+

isinstance(x, (tuple,list,L,slice,Generator))

+
+
assert is_listy((1,))
+assert is_listy([1])
+assert is_listy(L([1]))
+assert is_listy(slice(2))
+assert not is_listy(array([1]))
+
+
+

source

+
+
+

mapped

+
+
 mapped (f, it)
+
+

map f over it, unless it’s not listy, in which case return f(it)

+
+
def _f(x,a=1): return x-a
+
+test_eq(mapped(_f,1),0)
+test_eq(mapped(_f,[1,2]),[0,1])
+test_eq(mapped(_f,(1,)),(0,))
+
+
+
+
+

Extensions to Pathlib.Path

+

The following methods are added to the standard python libary Pathlib.Path.

+
+

source

+
+

Path.readlines

+
+
 Path.readlines (hint=-1, encoding='utf8')
+
+

Read the content of self

+
+

source

+
+
+

Path.read_json

+
+
 Path.read_json (encoding=None, errors=None)
+
+

Same as read_text followed by loads

+
+

source

+
+
+

Path.mk_write

+
+
 Path.mk_write (data, encoding=None, errors=None, mode=511)
+
+

Make all parent dirs of self, and write data

+
+

source

+
+
+

Path.relpath

+
+
 Path.relpath (start=None)
+
+

Same as os.path.relpath, but returns a Path, and resolves symlinks

+
+
p = Path('../fastcore/').resolve()
+p
+
+
Path('/Users/jhoward/Documents/GitHub/fastcore/fastcore')
+
+
+
+
p.relpath(Path.cwd())
+
+
Path('../fastcore')
+
+
+
+

source

+
+
+

Path.ls

+
+
 Path.ls (n_max=None, file_type=None, file_exts=None)
+
+

Contents of path as a list

+

We add an ls() method to pathlib.Path which is simply defined as list(Path.iterdir()), mainly for convenience in REPL environments such as notebooks.

+
+
path = Path()
+t = path.ls()
+assert len(t)>0
+t1 = path.ls(10)
+test_eq(len(t1), 10)
+t2 = path.ls(file_exts='.ipynb')
+assert len(t)>len(t2)
+t[0]
+
+
Path('000_tour.ipynb')
+
+
+

You can also pass an optional file_type MIME prefix and/or a list of file extensions.

+
+
lib_path = (path/'../fastcore')
+txt_files=lib_path.ls(file_type='text')
+assert len(txt_files) > 0 and txt_files[0].suffix=='.py'
+ipy_files=path.ls(file_exts=['.ipynb'])
+assert len(ipy_files) > 0 and ipy_files[0].suffix=='.ipynb'
+txt_files[0],ipy_files[0]
+
+
(Path('../fastcore/shutil.py'), Path('000_tour.ipynb'))
+
+
+
+

source

+
+
+

Path.__repr__

+
+
 Path.__repr__ ()
+
+

Return repr(self).

+

fastai also updates the repr of Path such that, if Path.BASE_PATH is defined, all paths are printed relative to that path (as long as they are contained in Path.BASE_PATH:

+
+
t = ipy_files[0].absolute()
+try:
+    Path.BASE_PATH = t.parent.parent
+    test_eq(repr(t), f"Path('nbs/{t.name}')")
+finally: Path.BASE_PATH = None
+
+
+

source

+
+
+

Path.delete

+
+
 Path.delete ()
+
+

Delete a file, symlink, or directory tree

+
+
+
+

Reindexing Collections

+
+

source

+
+

ReindexCollection

+
+
 ReindexCollection (coll, idxs=None, cache=None, tfm=<function noop>)
+
+

Reindexes collection coll with indices idxs and optional LRU cache of size cache

+

This is useful when constructing batches or organizing data in a particular manner (i.e. for deep learning). This class is primarly used in organizing data for language models in fastai.

+

You can supply a custom index upon instantiation with the idxs argument, or you can call the reindex method to supply a new index for your collection.

+

Here is how you can reindex a list such that the elements are reversed:

+
+
rc=ReindexCollection(['a', 'b', 'c', 'd', 'e'], idxs=[4,3,2,1,0])
+list(rc)
+
+
['e', 'd', 'c', 'b', 'a']
+
+
+

Alternatively, you can use the reindex method:

+
+

source

+
+
ReindexCollection.reindex
+
+
 ReindexCollection.reindex (idxs)
+
+

Replace self.idxs with idxs

+
+
rc=ReindexCollection(['a', 'b', 'c', 'd', 'e'])
+rc.reindex([4,3,2,1,0])
+list(rc)
+
+
['e', 'd', 'c', 'b', 'a']
+
+
+

You can optionally specify a LRU cache, which uses functools.lru_cache upon instantiation:

+
+
sz = 50
+t = ReindexCollection(L.range(sz), cache=2)
+
+#trigger a cache hit by indexing into the same element multiple times
+t[0], t[0]
+t._get.cache_info()
+
+
CacheInfo(hits=1, misses=1, maxsize=2, currsize=1)
+
+
+

You can optionally clear the LRU cache by calling the cache_clear method:

+
+

source

+
+
+
ReindexCollection.cache_clear
+
+
 ReindexCollection.cache_clear ()
+
+

Clear LRU cache

+
+
sz = 50
+t = ReindexCollection(L.range(sz), cache=2)
+
+#trigger a cache hit by indexing into the same element multiple times
+t[0], t[0]
+t.cache_clear()
+t._get.cache_info()
+
+
CacheInfo(hits=0, misses=0, maxsize=2, currsize=0)
+
+
+
+

source

+
+
+
ReindexCollection.shuffle
+
+
 ReindexCollection.shuffle ()
+
+

Randomly shuffle indices

+

Note that an ordered index is automatically constructed for the data structure even if one is not supplied.

+
+
rc=ReindexCollection(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
+rc.shuffle()
+list(rc)
+
+
['b', 'a', 'd', 'e', 'c', 'g', 'h', 'f']
+
+
+
+
sz = 50
+t = ReindexCollection(L.range(sz), cache=2)
+test_eq(list(t), range(sz))
+test_eq(t[sz-1], sz-1)
+test_eq(t._get.cache_info().hits, 1)
+t.shuffle()
+test_eq(t._get.cache_info().hits, 1)
+test_ne(list(t), range(sz))
+test_eq(set(t), set(range(sz)))
+t.cache_clear()
+test_eq(t._get.cache_info().hits, 0)
+test_eq(t.count(0), 1)
+
+
+
+
+
+

Other Helpers

+
+

source

+ +
+

truncstr

+
+
 truncstr (s:str, maxlen:int, suf:str='…', space='')
+
+

Truncate s to length maxlen, adding suffix suf if truncated

+
+
w = 'abacadabra'
+test_eq(truncstr(w, 10), w)
+test_eq(truncstr(w, 5), 'abac…')
+test_eq(truncstr(w, 5, suf=''), 'abaca')
+test_eq(truncstr(w, 11, space='_'), w+"_")
+test_eq(truncstr(w, 10, space='_'), w[:-1]+'…')
+test_eq(truncstr(w, 5, suf='!!'), 'aba!!')
+
+
+

source

+
+
+

sparkline

+
+
 sparkline (data, mn=None, mx=None, empty_zero=False)
+
+

Sparkline for data, with Nones (and zero, if empty_zero) shown as empty column

+
+
data = [9,6,None,1,4,0,8,15,10]
+print(f'without "empty_zero": {sparkline(data, empty_zero=False)}')
+print(f'   with "empty_zero": {sparkline(data, empty_zero=True )}')
+
+
without "empty_zero": ▅▂ ▁▂▁▃▇▅
+   with "empty_zero": ▅▂ ▁▂ ▃▇▅
+
+
+

You can set a maximum and minimum for the y-axis of the sparkline with the arguments mn and mx respectively:

+
+
sparkline([1,2,3,400], mn=0, mx=3)
+
+
'▂▅▇▇'
+
+
+
+

source

+
+
+

modify_exception

+
+
 modify_exception (e:Exception, msg:str=None, replace:bool=False)
+
+

Modifies e with a custom message attached

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeDefaultDetails
eExceptionAn exception
msgstrNoneA custom message
replaceboolFalseWhether to replace e.args with [msg]
ReturnsException
+
+
msg = "This is my custom message!"
+
+test_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(), None)), contains='')
+test_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception(), msg)), contains=msg)
+test_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception("The first message"), msg)), contains="The first message This is my custom message!")
+test_fail(lambda: (_ for _ in ()).throw(modify_exception(Exception("The first message"), msg, True)), contains="This is my custom message!")
+
+
+

source

+
+
+

round_multiple

+
+
 round_multiple (x, mult, round_down=False)
+
+

Round x to nearest multiple of mult

+
+
test_eq(round_multiple(63,32), 64)
+test_eq(round_multiple(50,32), 64)
+test_eq(round_multiple(40,32), 32)
+test_eq(round_multiple( 0,32),  0)
+test_eq(round_multiple(63,32, round_down=True), 32)
+test_eq(round_multiple((63,40),32), (64,32))
+
+
+

source

+
+
+

set_num_threads

+
+
 set_num_threads (nt)
+
+

Get numpy (and others) to use nt threads

+

This sets the number of threads consistently for many tools, by:

+
    +
  1. Set the following environment variables equal to nt: OPENBLAS_NUM_THREADS,NUMEXPR_NUM_THREADS,OMP_NUM_THREADS,MKL_NUM_THREADS
  2. +
  3. Sets nt threads for numpy and pytorch.
  4. +
+
+

source

+
+
+

join_path_file

+
+
 join_path_file (file, path, ext='')
+
+

Return path/file if file is a string or a Path, file otherwise

+
+
path = Path.cwd()/'_tmp'/'tst'
+f = join_path_file('tst.txt', path)
+assert path.exists()
+test_eq(f, path/'tst.txt')
+with open(f, 'w') as f_: assert join_path_file(f_, path) == f_
+shutil.rmtree(Path.cwd()/'_tmp')
+
+
+

source

+
+
+

autostart

+
+
 autostart (g)
+
+

Decorator that automatically starts a generator

+
+

source

+
+

EventTimer

+
+
 EventTimer (store=5, span=60)
+
+

An event timer with history of store items of time span

+

Add events with add, and get number of events and their frequency (freq).

+
+
# Random wait function for testing
+def _randwait(): yield from (sleep(random.random()/200) for _ in range(100))
+
+c = EventTimer(store=5, span=0.03)
+for o in _randwait(): c.add(1)
+print(f'Num Events: {c.events}, Freq/sec: {c.freq:.01f}')
+print('Most recent: ', sparkline(c.hist), *L(c.hist).map('{:.01f}'))
+
+
Num Events: 7, Freq/sec: 346.4
+Most recent:  ▁▇▃▅▁ 295.9 396.4 324.8 356.6 262.6
+
+
+
+

source

+
+
+
+

stringfmt_names

+
+
 stringfmt_names (s:str)
+
+

Unique brace-delimited names in s

+
+
s = '/pulls/{pull_number}/reviews/{review_id}'
+test_eq(stringfmt_names(s), ['pull_number','review_id'])
+
+
+

source

+
+

PartialFormatter

+
+
 PartialFormatter ()
+
+

A string.Formatter that doesn’t error on missing fields, and tracks missing fields and unused args

+
+

source

+
+
+
+

partial_format

+
+
 partial_format (s:str, **kwargs)
+
+

string format s, ignoring missing field errors, returning missing and extra fields

+

The result is a tuple of (formatted_string,missing_fields,extra_fields), e.g:

+
+
res,missing,xtra = partial_format(s, pull_number=1, foo=2)
+test_eq(res, '/pulls/1/reviews/{review_id}')
+test_eq(missing, ['review_id'])
+test_eq(xtra, {'foo':2})
+
+
+

source

+
+
+

utc2local

+
+
 utc2local (dt:datetime.datetime)
+
+

Convert dt from UTC to local time

+
+
dt = datetime(2000,1,1,12)
+print(f'{dt} UTC is {utc2local(dt)} local time')
+
+
2000-01-01 12:00:00 UTC is 2000-01-01 22:00:00+10:00 local time
+
+
+
+

source

+
+
+

local2utc

+
+
 local2utc (dt:datetime.datetime)
+
+

Convert dt from local to UTC time

+
+
print(f'{dt} local is {local2utc(dt)} UTC time')
+
+
2000-01-01 12:00:00 local is 2000-01-01 02:00:00+00:00 UTC time
+
+
+
+

source

+
+
+

trace

+
+
 trace (f)
+
+

Add set_trace to an existing function f

+

You can add a breakpoint to an existing function, e.g:

+
Path.cwd = trace(Path.cwd)
+Path.cwd()
+

Now, when the function is called it will drop you into the debugger. Note, you must issue the s command when you begin to step into the function that is being traced.

+
+

source

+
+
+

modified_env

+
+
 modified_env (*delete, **replace)
+
+

Context manager temporarily modifying os.environ by deleting delete and replacing replace

+
+
# USER isn't in Cloud Linux Environments
+env_test = 'USERNAME' if sys.platform == "win32" else 'SHELL'
+oldusr = os.environ[env_test]
+
+replace_param = {env_test: 'a'}
+with modified_env('PATH', **replace_param):
+    test_eq(os.environ[env_test], 'a')
+    assert 'PATH' not in os.environ
+
+assert 'PATH' in os.environ
+test_eq(os.environ[env_test], oldusr)
+
+
+

source

+
+

ContextManagers

+
+
 ContextManagers (mgrs)
+
+

Wrapper for contextlib.ExitStack which enters a collection of context managers

+
+

source

+
+
+
+

shufflish

+
+
 shufflish (x, pct=0.04)
+
+

Randomly relocate items of x up to pct of len(x) from their starting location

+
+

source

+
+
+

console_help

+
+
 console_help (libname:str)
+
+

Show help for all console scripts from libname

+ + + + + + + + + + + + + + + +
TypeDetails
libnamestrname of library for console script listing
+
+

source

+
+
+

hl_md

+
+
 hl_md (s, lang='xml', show=True)
+
+

Syntax highlight s using lang.

+

When we display code in a notebook, it’s nice to highlight it, so we create a function to simplify that:

+
+
hl_md('<test><xml foo="bar">a child</xml></test>')
+
+
<test><xml foo="bar">a child</xml></test>
+
+
+
+

source

+
+
+

type2str

+
+
 type2str (typ:type)
+
+

Stringify typ

+
+
test_eq(type2str(Optional[float]), 'Union[float, None]')
+
+
+

source

+
+
+

dataclass_src

+
+
 dataclass_src (cls)
+
+
+
DC = make_dataclass('DC', [('x', int), ('y', Optional[float], None), ('z', float, None)])
+print(dataclass_src(DC))
+
+
@dataclass
+class DC:
+    x: int
+    y: Union[float, None] = None
+    z: float = None
+
+
+
+
+

source

+
+
+

Unset

+
+
 Unset (value, names=None, module=None, qualname=None, type=None, start=1)
+
+

An enumeration.

+
+

source

+
+
+

nullable_dc

+
+
 nullable_dc (cls)
+
+

Like dataclass, but default of UNSET added to fields without defaults

+
+
@nullable_dc
+class Person: name: str; age: int; city: str = "Unknown"
+Person(name="Bob")
+
+
Person(name='Bob', age=UNSET, city='Unknown')
+
+
+
+

source

+
+
+

make_nullable

+
+
 make_nullable (clas)
+
+
+
@dataclass
+class Person: name: str; age: int; city: str = "Unknown"
+
+make_nullable(Person)
+Person("Bob", city='NY')
+
+
Person(name='Bob', age=UNSET, city='NY')
+
+
+
+
Person(name="Bob")
+
+
Person(name='Bob', age=UNSET, city='Unknown')
+
+
+
+
Person("Bob", 34)
+
+
Person(name='Bob', age=34, city='Unknown')
+
+
+
+

source

+
+
+

flexiclass

+
+
 flexiclass (cls)
+
+

Convert cls into a dataclass like make_nullable

+

This can be used as a decorator…

+
+
@flexiclass
+class Person: name: str; age: int; city: str = "Unknown"
+
+bob = Person(name="Bob")
+bob
+
+
Person(name='Bob', age=UNSET, city='Unknown')
+
+
+

…or can update the behavior of an existing class (or dataclass):

+
+
class Person: name: str; age: int; city: str = "Unknown"
+
+flexiclass(Person)
+bob = Person(name="Bob")
+bob
+
+
Person(name='Bob', age=UNSET, city='Unknown')
+
+
+
+

source

+
+
+

asdict

+
+
 asdict (o)
+
+

Convert o to a dict, supporting dataclasses, namedtuples, iterables, and __dict__ attrs.

+

Any UNSET values are not included.

+
+
asdict(bob)
+
+
{'name': 'Bob', 'city': 'Unknown'}
+
+
+

To customise dict conversion behavior for a class, implement the _asdict method (this is used in the Python stdlib for named tuples).

+
+

source

+
+
+

is_typeddict

+
+
 is_typeddict (cls:type)
+
+

Check if cls is a TypedDict

+
+
class MyDict(TypedDict): name:str
+
+assert is_typeddict(MyDict)
+assert not is_typeddict({'a':1})
+
+
+

source

+
+
+

is_namedtuple

+
+
 is_namedtuple (cls)
+
+

True if cls is a namedtuple type

+
+
assert is_namedtuple(namedtuple('tst', ['a']))
+assert not is_namedtuple(tuple)
+
+
+

source

+
+
+

flexicache

+
+
 flexicache (*funcs, maxsize=128)
+
+

Like lru_cache, but customisable with policy funcs

+

This is a flexible lru cache function that you can pass a list of functions to. Those functions define the cache eviction policy. For instance, time_policy is provided for time-based cache eviction, and mtime_policy evicts based on a file’s modified-time changing. The policy functions are passed the last value that function returned was (initially None), and return a new value to indicate the cache has expired. When the cache expires, all functions are called with None to force getting new values.

+
+

source

+
+
+

time_policy

+
+
 time_policy (seconds)
+
+

A flexicache policy that expires cached items after seconds have passed

+
+

source

+
+
+

mtime_policy

+
+
 mtime_policy (filepath)
+
+

A flexicache policy that expires cached items after filepath modified-time changes

+
+
@flexicache(time_policy(10), mtime_policy('000_tour.ipynb'))
+def cached_func(x, y): return x+y
+
+cached_func(1,2)
+
+
3
+
+
+
+
@flexicache(time_policy(10), mtime_policy('000_tour.ipynb'))
+async def cached_func(x, y): return x+y
+
+await cached_func(1,2)
+await cached_func(1,2)
+
+
3
+
+
+
+

source

+
+
+

timed_cache

+
+
 timed_cache (seconds=60, maxsize=128)
+
+

Like lru_cache, but also with time-based eviction

+

This function is a small convenience wrapper for using flexicache with time_policy.

+
+
@timed_cache(seconds=0.05, maxsize=2)
+def cached_func(x): return x * 2, time()
+
+# basic caching
+result1, time1 = cached_func(2)
+test_eq(result1, 4)
+sleep(0.001)
+result2, time2 = cached_func(2)
+test_eq(result2, 4)
+test_eq(time1, time2)
+
+# caching different values
+result3, _ = cached_func(3)
+test_eq(result3, 6)
+
+# maxsize
+_, time4 = cached_func(4)
+_, time2_new = cached_func(2)
+test_close(time2, time2_new, eps=0.1)
+_, time3_new = cached_func(3)
+test_ne(time3_new, time())
+
+# time expiration
+sleep(0.05)
+_, time4_new = cached_func(4)
+test_ne(time4_new, time())
+
+ + +
+
+ +
+ +
+ + + + + \ No newline at end of file
+ + +