diff --git a/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini index 3605e8f3fc9..76b44d9e9cf 100644 --- a/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini +++ b/tests/wpt/metadata-layout-2020/FileAPI/url/url-in-tags-revoke.window.js.ini @@ -4,7 +4,7 @@ expected: TIMEOUT [Opening a blob URL in a new window immediately before revoking it works.] - expected: TIMEOUT + expected: FAIL [Fetching a blob URL immediately before revoking it works in an iframe.] expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-002.html.ini b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-002.html.ini deleted file mode 100644 index f64b45fea6b..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-002.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[hit-test-floats-002.html] - [Hit test float] - expected: FAIL - diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini deleted file mode 100644 index f29da48a2a0..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-003.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[hit-test-floats-003.html] - [Miss float below something else] - expected: FAIL - diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-005.html.ini b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-005.html.ini new file mode 100644 index 00000000000..baa9f1a7541 --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/CSS2/floats/hit-test-floats-005.html.ini @@ -0,0 +1,4 @@ +[hit-test-floats-005.html] + [Miss clipped float] + expected: FAIL + diff --git a/tests/wpt/metadata-layout-2020/css/css-text/white-space/white-space-letter-spacing-001.html.ini b/tests/wpt/metadata-layout-2020/css/css-text/white-space/white-space-letter-spacing-001.html.ini new file mode 100644 index 00000000000..ea0c28afe9a --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/css-text/white-space/white-space-letter-spacing-001.html.ini @@ -0,0 +1,2 @@ +[white-space-letter-spacing-001.html] + expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-001.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-001.html.ini new file mode 100644 index 00000000000..2e8dcfc89a8 --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-001.html.ini @@ -0,0 +1,2 @@ +[subpixel-transform-changes-001.html] + expected: TIMEOUT diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-002.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-002.html.ini new file mode 100644 index 00000000000..13987e51a4f --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-002.html.ini @@ -0,0 +1,2 @@ +[subpixel-transform-changes-002.html] + expected: TIMEOUT diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-003.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-003.html.ini new file mode 100644 index 00000000000..f9bfdc9711e --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/css-transforms/subpixel-transform-changes-003.html.ini @@ -0,0 +1,2 @@ +[subpixel-transform-changes-003.html] + expected: TIMEOUT diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-scale-hittest.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-scale-hittest.html.ini index f8e7e539aae..4a1e8110f6f 100644 --- a/tests/wpt/metadata-layout-2020/css/css-transforms/transform-scale-hittest.html.ini +++ b/tests/wpt/metadata-layout-2020/css/css-transforms/transform-scale-hittest.html.ini @@ -2,6 +2,3 @@ [Hit test intersecting scaled box] expected: FAIL - [Hit test within unscaled box] - expected: FAIL - diff --git a/tests/wpt/metadata-layout-2020/css/cssom-view/CaretPosition-001.html.ini b/tests/wpt/metadata-layout-2020/css/cssom-view/CaretPosition-001.html.ini new file mode 100644 index 00000000000..4c79907309b --- /dev/null +++ b/tests/wpt/metadata-layout-2020/css/cssom-view/CaretPosition-001.html.ini @@ -0,0 +1,4 @@ +[CaretPosition-001.html] + [Element at (400, 100)] + expected: FAIL + diff --git a/tests/wpt/metadata-layout-2020/css/cssom-view/MediaQueryList-addListener-removeListener.html.ini b/tests/wpt/metadata-layout-2020/css/cssom-view/MediaQueryList-addListener-removeListener.html.ini index c884dc82eab..628b1fab770 100644 --- a/tests/wpt/metadata-layout-2020/css/cssom-view/MediaQueryList-addListener-removeListener.html.ini +++ b/tests/wpt/metadata-layout-2020/css/cssom-view/MediaQueryList-addListener-removeListener.html.ini @@ -2,6 +2,3 @@ [listeners are called when + + diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers new file mode 100644 index 00000000000..fd9ee0f0328 --- /dev/null +++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.html.headers @@ -0,0 +1,2 @@ +Content-Security-Policy: upgrade-insecure-requests +Referrer-Policy: origin-when-cross-origin diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html new file mode 100644 index 00000000000..243efb76719 --- /dev/null +++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers new file mode 100644 index 00000000000..fd9ee0f0328 --- /dev/null +++ b/tests/wpt/web-platform-tests/referrer-policy/generic/iframe-upgrade-request.sub.https.html.headers @@ -0,0 +1,2 @@ +Content-Security-Policy: upgrade-insecure-requests +Referrer-Policy: origin-when-cross-origin diff --git a/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py b/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py new file mode 100644 index 00000000000..ada048dc490 --- /dev/null +++ b/tests/wpt/web-platform-tests/referrer-policy/generic/resources/referrer.py @@ -0,0 +1,3 @@ +def main(request, response): + response_headers = [(b"Access-Control-Allow-Origin", b"*")] + return (200, response_headers, request.headers.get("referer", "")) diff --git a/tests/wpt/web-platform-tests/resource-timing/SyntheticResponse.py b/tests/wpt/web-platform-tests/resource-timing/SyntheticResponse.py index c5158002f18..dc57d8451f9 100644 --- a/tests/wpt/web-platform-tests/resource-timing/SyntheticResponse.py +++ b/tests/wpt/web-platform-tests/resource-timing/SyntheticResponse.py @@ -1,23 +1,28 @@ -import urllib +from six.moves.urllib.parse import unquote + +from wptserve.utils import isomorphic_decode, isomorphic_encode + import sleep def main(request, response): - index = request.request_path.index("?") - args = request.request_path[index+1:].split("&") + index = isomorphic_encode(request.request_path).index(b"?") + args = isomorphic_encode(request.request_path[index+1:]).split(b"&") headers = [] statusSent = False headersSent = False for arg in args: - if arg.startswith("ignored"): + if arg.startswith(b"ignored"): continue - elif arg.endswith("ms"): + elif arg.endswith(b"ms"): sleep.sleep_at_least(float(arg[0:-2])) - elif arg.startswith("redirect:"): - return (302, "WEBPERF MARKETING"), [("Location", urllib.unquote(arg[9:]))], "TEST" - elif arg.startswith("mime:"): - headers.append(("Content-Type", urllib.unquote(arg[5:]))) - elif arg.startswith("send:"): - text = urllib.unquote(arg[5:]) + elif arg.startswith(b"redirect:"): + return (302, u"WEBPERF MARKETING"), [(b"Location", unquote(isomorphic_decode(arg[9:])))], u"TEST" + + elif arg.startswith(b"mime:"): + headers.append((b"Content-Type", unquote(isomorphic_decode(arg[5:])))) + + elif arg.startswith(b"send:"): + text = unquote(isomorphic_decode(arg[5:])) if not statusSent: # Default to a 200 status code. @@ -30,15 +35,15 @@ def main(request, response): headersSent = True response.writer.write_content(text) - elif arg.startswith("status:"): - code = int(urllib.unquote(arg[7:])) + elif arg.startswith(b"status:"): + code = int(unquote(isomorphic_decode(arg[7:]))) response.writer.write_status(code) if code // 100 == 1: # Terminate informational 1XX responses with an empty line. response.writer.end_headers() else: statusSent = True - elif arg == "flush": + elif arg == b"flush": response.writer.flush() # else: diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py b/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py index e84912808da..908b68861ae 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/TAOResponse.py @@ -1,51 +1,51 @@ def main(request, response): - origin = request.headers['origin'] - response.headers.set('Access-Control-Allow-Origin', origin) + origin = request.headers[b'origin'] + response.headers.set(b'Access-Control-Allow-Origin', origin) - tao = request.GET.first('tao') + tao = request.GET.first(b'tao') - if tao == 'zero': + if tao == b'zero': # zero TAO value, fail pass - elif tao == 'wildcard': + elif tao == b'wildcard': # wildcard, pass - response.headers.set('Timing-Allow-Origin', '*') - elif tao == 'null': + response.headers.set(b'Timing-Allow-Origin', b'*') + elif tao == b'null': # null, fail unless it's an opaque origin - response.headers.set('Timing-Allow-Origin', 'null') - elif tao == 'Null': + response.headers.set(b'Timing-Allow-Origin', b'null') + elif tao == b'Null': # case-insentive null, fail - response.headers.set('Timing-Allow-Origin', 'Null') - elif tao == 'origin': + response.headers.set(b'Timing-Allow-Origin', b'Null') + elif tao == b'origin': # case-sensitive match for origin, pass - response.headers.set('Timing-Allow-Origin', origin) - elif tao.startswith('origin_port'): + response.headers.set(b'Timing-Allow-Origin', origin) + elif tao.startswith(b'origin_port'): # case-sensitive match for origin and port, pass - origin_parts = origin.split(':') - host = origin_parts[0] + ':' + origin_parts[1] - port = tao.split('origin_port_')[1] - response.headers.set('Timing-Allow-Origin', host + ':' + port) - elif tao == 'space': + origin_parts = origin.split(b':') + host = origin_parts[0] + b':' + origin_parts[1] + port = tao.split(b'origin_port_')[1] + response.headers.set(b'Timing-Allow-Origin', host + b':' + port) + elif tao == b'space': # space separated list of origin and wildcard, fail - response.headers.set('Timing-Allow-Origin', (origin + ' *')) - elif tao == 'multi': + response.headers.set(b'Timing-Allow-Origin', (origin + b' *')) + elif tao == b'multi': # more than one TAO values, separated by comma, pass - response.headers.set('Timing-Allow-Origin', origin) - response.headers.append('Timing-Allow-Origin', '*') - elif tao == 'multi_wildcard': + response.headers.set(b'Timing-Allow-Origin', origin) + response.headers.append(b'Timing-Allow-Origin', b'*') + elif tao == b'multi_wildcard': # multiple wildcards, separated by comma, pass - response.headers.set('Timing-Allow-Origin', '*') - response.headers.append('Timing-Allow-Origin', '*') - elif tao == 'match_origin': + response.headers.set(b'Timing-Allow-Origin', b'*') + response.headers.append(b'Timing-Allow-Origin', b'*') + elif tao == b'match_origin': # contains a match of origin, separated by comma, pass - response.headers.set('Timing-Allow-Origin', origin) - response.headers.append('Timing-Allow-Origin', "fake") - elif tao == 'match_wildcard': + response.headers.set(b'Timing-Allow-Origin', origin) + response.headers.append(b'Timing-Allow-Origin', b"fake") + elif tao == b'match_wildcard': # contains a wildcard, separated by comma, pass - response.headers.set('Timing-Allow-Origin', "fake") - response.headers.append('Timing-Allow-Origin', '*') - elif tao == 'uppercase': + response.headers.set(b'Timing-Allow-Origin', b"fake") + response.headers.append(b'Timing-Allow-Origin', b'*') + elif tao == b'uppercase': # non-case-sensitive match for origin, fail - response.headers.set('Timing-Allow-Origin', origin.upper()) + response.headers.set(b'Timing-Allow-Origin', origin.upper()) else: pass diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/cors-ahem.py b/tests/wpt/web-platform-tests/resource-timing/resources/cors-ahem.py index 1998d47c492..7666b771ac3 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/cors-ahem.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/cors-ahem.py @@ -1,17 +1,19 @@ import os.path -def main(request, response): - etag = "123abc" - if etag == request.headers.get("If-None-Match", None): - response.headers.set("X-HTTP-STATUS", 304) - response.status = (304, "Not Modified") - return "" +from wptserve.utils import isomorphic_decode - response.headers.set("Cache-Control", "public, max-age=86400") - response.headers.set("Content-Type", "font/truetype") - response.headers.set("Access-Control-Allow-Origin", "*") - response.headers.set("Timing-Allow-Origin", "*") - response.headers.set("ETag", etag) - font = "../../fonts/Ahem.ttf" - path = os.path.join(os.path.dirname(__file__), font) - response.content = open(path, "rb").read() +def main(request, response): + etag = b"123abc" + if etag == request.headers.get(b"If-None-Match", None): + response.headers.set(b"X-HTTP-STATUS", 304) + response.status = (304, u"Not Modified") + return u"" + + response.headers.set(b"Cache-Control", b"public, max-age=86400") + response.headers.set(b"Content-Type", b"font/truetype") + response.headers.set(b"Access-Control-Allow-Origin", b"*") + response.headers.set(b"Timing-Allow-Origin", b"*") + response.headers.set(b"ETag", etag) + font = u"../../fonts/Ahem.ttf" + path = os.path.join(os.path.dirname(isomorphic_decode(__file__)), font) + response.content = open(path, u"rb").read() diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/empty.py b/tests/wpt/web-platform-tests/resource-timing/resources/empty.py index e5ccfbe9739..cae83c146e4 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/empty.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/empty.py @@ -1,3 +1,3 @@ def main(request, response): - response.headers.set("Content-Type", "text/plain") - return "" + response.headers.set(b"Content-Type", b"text/plain") + return u"" diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/eventsource.py b/tests/wpt/web-platform-tests/resource-timing/resources/eventsource.py index 5095ea9b34f..e3a2355730a 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/eventsource.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/eventsource.py @@ -1,3 +1,3 @@ def main(request, response): - response.headers.set("Content-Type", "text/event-stream") - return "" + response.headers.set(b"Content-Type", b"text/event-stream") + return u"" diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/fake_responses.py b/tests/wpt/web-platform-tests/resource-timing/resources/fake_responses.py index 289c1793176..359d7cfcff7 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/fake_responses.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/fake_responses.py @@ -1,26 +1,26 @@ # /xhr/resources/conditional.py -- to fake a 304 response def main(request, response): - tag = request.GET.first("tag", None) - redirect = request.GET.first("redirect", None) - match = request.headers.get("If-None-Match", None) - date = request.GET.first("date", "") - modified = request.headers.get("If-Modified-Since", None) - response.headers.set("Access-Control-Allow-Origin", "*"); - response.headers.set("Timing-Allow-Origin", "*"); + tag = request.GET.first(b"tag", None) + redirect = request.GET.first(b"redirect", None) + match = request.headers.get(b"If-None-Match", None) + date = request.GET.first(b"date", b"") + modified = request.headers.get(b"If-Modified-Since", None) + response.headers.set(b"Access-Control-Allow-Origin", b"*"); + response.headers.set(b"Timing-Allow-Origin", b"*"); if tag: - response.headers.set("ETag", '"%s"' % tag) + response.headers.set(b"ETag", b'"%s"' % tag) elif date: - response.headers.set("Last-Modified", date) + response.headers.set(b"Last-Modified", date) if redirect: - response.headers.set("Location", redirect) - response.status = (302, "Moved") - return "" + response.headers.set(b"Location", redirect) + response.status = (302, u"Moved") + return u"" if ((match is not None and match == tag) or (modified is not None and modified == date)): - response.status = (304, "SUPERCOOL") - return "" + response.status = (304, u"SUPERCOOL") + return u"" else: - response.headers.set("Content-Type", "text/plain") - return "MAYBE NOT" + response.headers.set(b"Content-Type", b"text/plain") + return u"MAYBE NOT" diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/gzip_xml.py b/tests/wpt/web-platform-tests/resource-timing/resources/gzip_xml.py index 31a769eb366..2293605ac33 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/gzip_xml.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/gzip_xml.py @@ -1,20 +1,23 @@ import gzip as gzip_module -from cStringIO import StringIO import os +from six import BytesIO + +from wptserve.utils import isomorphic_decode + def main(request, response): - dir_path = os.path.dirname(os.path.realpath(__file__)) - file_path = os.path.join(dir_path, 'resource_timing_test0.xml') - f = open(file_path, 'r') + dir_path = os.path.dirname(os.path.realpath(isomorphic_decode(__file__))) + file_path = os.path.join(dir_path, u'resource_timing_test0.xml') + f = open(file_path, u'rb') output = f.read() - out = StringIO() + out = BytesIO() with gzip_module.GzipFile(fileobj=out, mode="w") as f: - f.write(output) + f.write(output) output = out.getvalue() - headers = [("Content-type", "text/plain"), - ("Content-Encoding", "gzip"), - ("Content-Length", len(output))] + headers = [(b"Content-type", b"text/plain"), + (b"Content-Encoding", b"gzip"), + (b"Content-Length", len(output))] return headers, output diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/multi_redirect.py b/tests/wpt/web-platform-tests/resource-timing/resources/multi_redirect.py index 037d986c723..56f5d6c7715 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/multi_redirect.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/multi_redirect.py @@ -1,3 +1,5 @@ +from wptserve.utils import isomorphic_encode + def main(request, response): """Handler that causes multiple redirections. Redirect chain is as follows: 1. Initial URL containing multi-redirect.py @@ -14,44 +16,43 @@ def main(request, response): Note that |step| is a parameter used internally for the multi-redirect. It's the step we're at in the redirect chain. """ step = 1 - if "step" in request.GET: + if b"step" in request.GET: try: - step = int(request.GET.first("step")) + step = int(request.GET.first(b"step")) except ValueError: pass - origin = request.url_parts.scheme + "://" + request.url_parts.hostname + ":" + str(request.url_parts.port) - page_origin = request.GET.first("page_origin") - cross_origin = request.GET.first("cross_origin") - final_resource = request.GET.first("final_resource") + page_origin = request.GET.first(b"page_origin") + cross_origin = request.GET.first(b"cross_origin") + final_resource = request.GET.first(b"final_resource") - tao_value = "*"; - if "tao_value" in request.GET: - tao_value = request.GET.first("tao_value") + tao_value = b"*" + if b"tao_value" in request.GET: + tao_value = request.GET.first(b"tao_value") tao_steps = 0 - if "tao_steps" in request.GET: - tao_steps = int(request.GET.first("tao_steps")) + if b"tao_steps" in request.GET: + tao_steps = int(request.GET.first(b"tao_steps")) next_tao_steps = tao_steps - 1 - redirect_url_path = "/resource-timing/resources/multi_redirect.py?" - redirect_url_path += "page_origin=" + page_origin - redirect_url_path += "&cross_origin=" + cross_origin - redirect_url_path += "&final_resource=" + final_resource - redirect_url_path += "&tao_value=" + tao_value - redirect_url_path += "&tao_steps=" + str(next_tao_steps) - redirect_url_path += "&step=" + redirect_url_path = b"/resource-timing/resources/multi_redirect.py?" + redirect_url_path += b"page_origin=" + page_origin + redirect_url_path += b"&cross_origin=" + cross_origin + redirect_url_path += b"&final_resource=" + final_resource + redirect_url_path += b"&tao_value=" + tao_value + redirect_url_path += b"&tao_steps=" + isomorphic_encode(str(next_tao_steps)) + redirect_url_path += b"&step=" if tao_steps > 0: - response.headers.set("timing-allow-origin", tao_value) + response.headers.set(b"timing-allow-origin", tao_value) if step == 1: # On the first request, redirect to a cross origin URL - redirect_url = cross_origin + redirect_url_path + "2" + redirect_url = cross_origin + redirect_url_path + b"2" elif step == 2: # On the second request, redirect to a same origin URL - redirect_url = page_origin + redirect_url_path + "3" + redirect_url = page_origin + redirect_url_path + b"3" else: # On the third request, redirect to a static response redirect_url = page_origin + final_resource response.status = 302 - response.headers.set("Location", redirect_url) + response.headers.set(b"Location", redirect_url) diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/preflight.py b/tests/wpt/web-platform-tests/resource-timing/resources/preflight.py index 4fca99d0717..168850e2a88 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/preflight.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/preflight.py @@ -1,8 +1,8 @@ def main(request, response): - response.headers.set("Access-Control-Allow-Origin", "*"); - response.headers.set("Access-Control-Max-Age", "0"); - response.headers.set("Timing-Allow-Origin", "*"); + response.headers.set(b"Access-Control-Allow-Origin", b"*"); + response.headers.set(b"Access-Control-Max-Age", b"0"); + response.headers.set(b"Timing-Allow-Origin", b"*"); # If this script is accessed with the header X-Require-Preflight then the # browser will send a preflight request. Otherwise it won't. - if request.method == 'OPTIONS': - response.headers.set("Access-Control-Allow-Headers", "X-Require-Preflight"); + if request.method == u'OPTIONS': + response.headers.set(b"Access-Control-Allow-Headers", b"X-Require-Preflight"); diff --git a/tests/wpt/web-platform-tests/resource-timing/resources/status-code.py b/tests/wpt/web-platform-tests/resource-timing/resources/status-code.py index 6ddad159524..9bc02bd3467 100644 --- a/tests/wpt/web-platform-tests/resource-timing/resources/status-code.py +++ b/tests/wpt/web-platform-tests/resource-timing/resources/status-code.py @@ -1,4 +1,4 @@ def main(request, response): - status = request.GET.first('status') - response.status = (status, ""); + status = request.GET.first(b'status') + response.status = (status, b""); diff --git a/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-before-closing-tag.html b/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-before-closing-tag.html new file mode 100644 index 00000000000..653c41918d1 --- /dev/null +++ b/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-before-closing-tag.html @@ -0,0 +1,42 @@ + +Declarative Shadow DOM innerHTML + + + + + + + + +
+ +
+ + + diff --git a/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-on-ordinary-template.html b/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-on-ordinary-template.html new file mode 100644 index 00000000000..988acc0ac79 --- /dev/null +++ b/tests/wpt/web-platform-tests/shadow-dom/declarative/innerhtml-on-ordinary-template.html @@ -0,0 +1,47 @@ + +Declarative Shadow DOM innerHTML + + + + + + + + +
+ + + +
+ + + diff --git a/tests/wpt/web-platform-tests/tools/.gitignore b/tests/wpt/web-platform-tests/tools/.gitignore index f888ce9935a..c59f948fdbe 100644 --- a/tests/wpt/web-platform-tests/tools/.gitignore +++ b/tests/wpt/web-platform-tests/tools/.gitignore @@ -10,3 +10,8 @@ coverage.xml *~ \#* runner/MANIFEST.json + +# WAVE +!wave/www/lib +!wave/export/lib +!wave/export/css diff --git a/tests/wpt/web-platform-tests/tools/ci/ci_tools_integration_test.sh b/tests/wpt/web-platform-tests/tools/ci/ci_tools_integration_test.sh index 7c37e7863e0..6929fb8ee0f 100755 --- a/tests/wpt/web-platform-tests/tools/ci/ci_tools_integration_test.sh +++ b/tests/wpt/web-platform-tests/tools/ci/ci_tools_integration_test.sh @@ -8,8 +8,16 @@ cd $WPT_ROOT main() { git fetch --quiet --unshallow https://github.com/web-platform-tests/wpt.git +refs/heads/*:refs/remotes/origin/* pip install --user -U tox codecov + + # wpt commands integration tests cd tools/wpt tox + cd $WPT_ROOT + + # WMAS test runner integration tests + cd tools/wave + tox + cd $WPT_ROOT } main diff --git a/tests/wpt/web-platform-tests/tools/pytest.ini b/tests/wpt/web-platform-tests/tools/pytest.ini index 6bdb4d563f6..140ce236ffd 100644 --- a/tests/wpt/web-platform-tests/tools/pytest.ini +++ b/tests/wpt/web-platform-tests/tools/pytest.ini @@ -1,5 +1,5 @@ [pytest] -norecursedirs = .* {arch} *.egg html5lib third_party pywebsocket six wpt wptrunner +norecursedirs = .* {arch} *.egg html5lib third_party pywebsocket six wave wpt wptrunner xfail_strict = true addopts = --strict-markers markers = diff --git a/tests/wpt/web-platform-tests/tools/serve/commands.json b/tests/wpt/web-platform-tests/tools/serve/commands.json index abcb2970b63..a5457b55a33 100644 --- a/tests/wpt/web-platform-tests/tools/serve/commands.json +++ b/tests/wpt/web-platform-tests/tools/serve/commands.json @@ -1,2 +1,18 @@ -{"serve": {"path": "serve.py", "script": "run", "parser": "get_parser", "help": "Run wptserve server", - "virtualenv": false}} +{ + "serve": { + "path": "serve.py", + "script": "run", + "parser": "get_parser", + "help": "Run wptserve server", + "virtualenv": false + }, + "serve-wave": { + "path": "wave.py", + "script": "run", + "parser": "get_parser", + "help": "Run wptserve server for WAVE", + "virtualenv": true, + "install": ["ua-parser"], + "requirements": ["../wave/requirements.txt"] + } +} diff --git a/tests/wpt/web-platform-tests/tools/serve/serve.py b/tests/wpt/web-platform-tests/tools/serve/serve.py index d98c81eafbb..db15ba4833c 100644 --- a/tests/wpt/web-platform-tests/tools/serve/serve.py +++ b/tests/wpt/web-platform-tests/tools/serve/serve.py @@ -328,7 +328,8 @@ class RoutesBuilder(object): self.forbidden = [("*", "/_certs/*", handlers.ErrorHandler(404)), ("*", "/tools/*", handlers.ErrorHandler(404)), - ("*", "{spec}/tools/*", handlers.ErrorHandler(404))] + ("*", "{spec}/tools/*", handlers.ErrorHandler(404)), + ("*", "/results/", handlers.ErrorHandler(404))] self.extra = [] @@ -384,7 +385,7 @@ class RoutesBuilder(object): self.mountpoint_routes[file_url] = [("GET", file_url, handlers.FileHandler(base_path=base_path, url_base=url_base))] -def build_routes(aliases): +def get_route_builder(aliases, config=None): builder = RoutesBuilder() for alias in aliases: url = alias["url-path"] @@ -396,7 +397,7 @@ def build_routes(aliases): builder.add_mount_point(url, directory) else: builder.add_file_mount_point(url, directory) - return builder.get_routes() + return builder class ServerProc(object): @@ -450,17 +451,16 @@ class ServerProc(object): return self.proc.is_alive() -def check_subdomains(config): +def check_subdomains(config, routes): paths = config.paths bind_address = config.bind_address - aliases = config.aliases host = config.server_host port = get_port() logger.debug("Going to use port %d to check subdomains" % port) wrapper = ServerProc() - wrapper.start(start_http_server, host, port, paths, build_routes(aliases), + wrapper.start(start_http_server, host, port, paths, routes, bind_address, config) url = "http://{}:{}/".format(host, port) @@ -780,45 +780,6 @@ def iter_procs(servers): yield server.proc -def build_config(override_path=None, **kwargs): - rv = ConfigBuilder() - - enable_http2 = kwargs.get("h2") - if enable_http2 is None: - enable_http2 = True - if enable_http2: - rv._default["ports"]["h2"] = [9000] - if kwargs.get("quic_transport"): - rv._default["ports"]["quic-transport"] = [10000] - - if override_path and os.path.exists(override_path): - with open(override_path) as f: - override_obj = json.load(f) - rv.update(override_obj) - - if kwargs.get("config_path"): - other_path = os.path.abspath(os.path.expanduser(kwargs.get("config_path"))) - if os.path.exists(other_path): - with open(other_path) as f: - override_obj = json.load(f) - rv.update(override_obj) - else: - raise ValueError("Config path %s does not exist" % other_path) - - overriding_path_args = [("doc_root", "Document root"), - ("ws_doc_root", "WebSockets document root")] - for key, title in overriding_path_args: - value = kwargs.get(key) - if value is None: - continue - value = os.path.abspath(os.path.expanduser(value)) - if not os.path.exists(value): - raise ValueError("%s path %s does not exist" % (title, value)) - setattr(rv, key, value) - - return rv - - def _make_subdomains_product(s, depth=2): return {u".".join(x) for x in chain(*(product(s, repeat=i) for i in range(1, depth+1)))} @@ -925,6 +886,43 @@ class ConfigBuilder(config.ConfigBuilder): return rv +def build_config(override_path=None, config_cls=ConfigBuilder, **kwargs): + rv = config_cls() + + enable_http2 = kwargs.get("h2") + if enable_http2 is None: + enable_http2 = True + if enable_http2: + rv._default["ports"]["h2"] = [9000] + + if override_path and os.path.exists(override_path): + with open(override_path) as f: + override_obj = json.load(f) + rv.update(override_obj) + + if kwargs.get("config_path"): + other_path = os.path.abspath(os.path.expanduser(kwargs.get("config_path"))) + if os.path.exists(other_path): + with open(other_path) as f: + override_obj = json.load(f) + rv.update(override_obj) + else: + raise ValueError("Config path %s does not exist" % other_path) + + overriding_path_args = [("doc_root", "Document root"), + ("ws_doc_root", "WebSockets document root")] + for key, title in overriding_path_args: + value = kwargs.get(key) + if value is None: + continue + value = os.path.abspath(os.path.expanduser(value)) + if not os.path.exists(value): + raise ValueError("%s path %s does not exist" % (title, value)) + setattr(rv, key, value) + + return rv + + def get_parser(): parser = argparse.ArgumentParser() parser.add_argument("--latency", type=int, @@ -942,13 +940,16 @@ def get_parser(): parser.add_argument("--no-h2", action="store_false", dest="h2", default=None, help="Disable the HTTP/2.0 server") parser.add_argument("--quic-transport", action="store_true", help="Enable QUIC server for WebTransport") + parser.set_defaults(report=False) + parser.set_defaults(is_wave=False) return parser -def run(**kwargs): +def run(config_cls=ConfigBuilder, route_builder=None, **kwargs): received_signal = threading.Event() with build_config(os.path.join(repo_root, "config.json"), + config_cls=config_cls, **kwargs) as config: global logger logger = config.logger @@ -971,8 +972,12 @@ def run(**kwargs): 'local-dir': doc_root, }) + if route_builder is None: + route_builder = get_route_builder + routes = route_builder(config.aliases, config).get_routes() + if config["check_subdomains"]: - check_subdomains(config) + check_subdomains(config, routes) stash_address = None if bind_address: @@ -980,7 +985,7 @@ def run(**kwargs): logger.debug("Going to use port %d for stash" % stash_address[1]) with stash.StashServer(stash_address, authkey=str(uuid.uuid4())): - servers = start(config, build_routes(config["aliases"]), **kwargs) + servers = start(config, routes, **kwargs) signal.signal(signal.SIGTERM, handle_signal) signal.signal(signal.SIGINT, handle_signal) diff --git a/tests/wpt/web-platform-tests/tools/serve/wave.py b/tests/wpt/web-platform-tests/tools/serve/wave.py new file mode 100644 index 00000000000..b13c6ef34de --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/serve/wave.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- + +import subprocess +from manifest import manifest +import localpaths +import logging +import os + +try: + from serve import serve +except ImportError: + import serve + +from tools.wpt import wpt + +global logger +logger = logging.getLogger("wave") + +def get_route_builder_func(report): + def get_route_builder(aliases, config=None): + wave_cfg = None + if config is not None and "wave" in config: + wave_cfg = config["wave"] + builder = serve.get_route_builder(aliases) + logger.debug("Loading manifest ...") + data = load_manifest() + from ..wave.wave_server import WaveServer + wave_server = WaveServer() + wave_server.initialize( + configuration_file_path=os.path.abspath("./config.json"), + reports_enabled=report, + tests=data["items"]) + + class WaveHandler(object): + def __call__(self, request, response): + wave_server.handle_request(request, response) + + web_root = "wave" + if wave_cfg is not None and "web_root" in wave_cfg: + web_root = wave_cfg["web_root"] + if not web_root.startswith("/"): + web_root = "/" + web_root + + wave_handler = WaveHandler() + builder.add_handler("*", web_root + "*", wave_handler) + # serving wave specifc testharnessreport.js + file_path = os.path.join(wpt.localpaths.repo_root, "tools/wave/resources/testharnessreport.js") + builder.add_static( + file_path, + {}, + "text/javascript;charset=utf8", + "/resources/testharnessreport.js") + + return builder + return get_route_builder + +class ConfigBuilder(serve.ConfigBuilder): + _default = serve.ConfigBuilder._default + _default.update({ + "wave": { # wave specific configuration parameters + "results": "./results", + "timeouts": { + "automatic": 60000, + "manual": 300000 + }, + "enable_results_import": False, + "web_root": "/_wave", + "persisting_interval": 20, + "api_titles": [] + } + }) + +def get_parser(): + parser = serve.get_parser() + # Added wave specific arguments + parser.add_argument("--report", action="store_true", dest="report", + help="Flag for enabling the WPTReporting server") + return parser + +def run(venv=None, **kwargs): + if venv is not None: + venv.start() + else: + raise Exception("Missing virtualenv for serve-wave.") + + if kwargs['report'] is True: + if not is_wptreport_installed(): + raise Exception("wptreport is not installed. Please install it from https://github.com/w3c/wptreport") + + serve.run(config_cls=ConfigBuilder, + route_builder=get_route_builder_func(kwargs["report"]), **kwargs) + +# execute wptreport version check +def is_wptreport_installed(): + try: + subprocess.check_output(["wptreport", "--help"]) + return True + except Exception: + return False + + +def load_manifest(): + root = localpaths.repo_root + path = os.path.join(root, "MANIFEST.json") + manifest_file = manifest.load_and_update(root, path, "/", parallel=False) + + supported_types = ["testharness", "manual"] + data = {"items": {}, + "url_base": "/"} + for item_type in supported_types: + data["items"][item_type] = {} + for item_type, path, tests in manifest_file.itertypes(*supported_types): + tests_data = [] + for item in tests: + test_data = [item.url[1:]] + if item_type == "reftest": + test_data.append(item.references) + test_data.append({}) + if item_type != "manual": + test_data[-1]["timeout"] = item.timeout + tests_data.append(test_data) + assert path not in data["items"][item_type] + data["items"][item_type][path] = tests_data + return data diff --git a/tests/wpt/web-platform-tests/tools/wave/__init__.py b/tests/wpt/web-platform-tests/tools/wave/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/config.default.json b/tests/wpt/web-platform-tests/tools/wave/config.default.json new file mode 100644 index 00000000000..8a05b91060a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/config.default.json @@ -0,0 +1,45 @@ +{ + "browser_host": "web-platform.test", + "alternate_hosts": { + "alt": "not-web-platform.test" + }, + "doc_root": ".", + "ws_doc_root": "./websockets/handlers", + "server_host": null, + "ports": { + "http": [8000, "auto"], + "https": [8443], + "ws": ["auto"], + "wss": ["auto"] + }, + "check_subdomains": true, + "log_level": "debug", + "bind_address": true, + "ssl": { + "type": "pregenerated", + "encrypt_after_connect": false, + "openssl": { + "openssl_binary": "openssl", + "base_path": "_certs", + "force_regenerate": false, + "base_conf_path": null + }, + "pregenerated": { + "host_key_path": "./tools/certs/web-platform.test.key", + "host_cert_path": "./tools/certs/web-platform.test.pem" + }, + "none": {} + }, + "aliases": [], + "wave": { + "results": "./results", + "timeouts": { + "automatic": 60000, + "manual": 300000 + }, + "enable_results_import": false, + "web_root": "/_wave", + "persisting_interval": 20, + "api_titles": [] + } +} diff --git a/tests/wpt/web-platform-tests/tools/wave/configuration_loader.py b/tests/wpt/web-platform-tests/tools/wave/configuration_loader.py new file mode 100644 index 00000000000..a94ebcd60a1 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/configuration_loader.py @@ -0,0 +1,81 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import json +import os +from io import open + +from tools.wpt import wpt + +DEFAULT_CONFIGURATION_FILE_PATH = os.path.join(wpt.localpaths.repo_root, "./tools/wave/config.default.json") + + +def load(configuration_file_path): + configuration = {} + if configuration_file_path: + configuration = load_configuration_file(configuration_file_path) + default_configuration = load_configuration_file( + DEFAULT_CONFIGURATION_FILE_PATH) + + configuration["wpt_port"] = configuration.get( + "ports", default_configuration["ports"]).get( + "http", default_configuration["ports"]["http"])[0] + configuration["wpt_ssl_port"] = configuration.get( + "ports", default_configuration["ports"]).get( + "https", default_configuration["ports"]["https"])[0] + + web_root = configuration.get( + "wave", default_configuration["wave"]).get( + "web_root", default_configuration["wave"]["web_root"]) + if not web_root.startswith("/"): + web_root = "/" + web_root + if not web_root.endswith("/"): + web_root += "/" + configuration["web_root"] = web_root + + configuration["results_directory_path"] = configuration.get( + "wave", default_configuration["wave"]).get( + "results", default_configuration["wave"]["results"]) + + configuration["timeouts"] = {} + configuration["timeouts"]["automatic"] = configuration.get( + "wave", default_configuration["wave"]).get( + "timeouts", default_configuration["wave"]["timeouts"]).get( + "automatic", default_configuration["wave"]["timeouts"]["automatic"]) + configuration["timeouts"]["manual"] = configuration.get( + "wave", default_configuration["wave"]).get( + "timeouts", default_configuration["wave"]["timeouts"]).get( + "manual", default_configuration["wave"]["timeouts"]["manual"]) + + configuration["hostname"] = configuration.get( + "browser_host", default_configuration["browser_host"]) + + configuration["import_enabled"] = configuration.get( + "wave", default_configuration["wave"]).get( + "enable_results_import", + default_configuration["wave"]["enable_results_import"]) + + configuration["persisting_interval"] = configuration.get( + "wave", default_configuration["wave"]).get( + "persisting_interval", default_configuration["wave"]["persisting_interval"]) + + configuration["tests_directory_path"] = os.getcwd() + + configuration["manifest_file_path"] = os.path.join( + os.getcwd(), "MANIFEST.json") + + configuration["api_titles"] = configuration.get( + "wave", default_configuration["wave"]).get( + "api_titles", default_configuration["wave"]["api_titles"]) + + return configuration + + +def load_configuration_file(path): + if not os.path.isfile(path): + return {} + + configuration = None + with open(path, "r") as configuration_file: + configuration_file_content = configuration_file.read() + configuration = json.loads(configuration_file_content) + return configuration diff --git a/tests/wpt/web-platform-tests/tools/wave/data/__init__.py b/tests/wpt/web-platform-tests/tools/wave/data/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/data/client.py b/tests/wpt/web-platform-tests/tools/wave/data/client.py new file mode 100644 index 00000000000..ab6851ab34b --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/client.py @@ -0,0 +1,6 @@ +class Client(object): + def __init__(self, session_token): + self.session_token = session_token + + def send_message(self, message): + raise Exception("Client.send_message(message) not implemented!") diff --git a/tests/wpt/web-platform-tests/tools/wave/data/exceptions/__init__.py b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/data/exceptions/duplicate_exception.py b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/duplicate_exception.py new file mode 100644 index 00000000000..2d64ea51bd9 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/duplicate_exception.py @@ -0,0 +1,2 @@ +class DuplicateException(Exception): + pass diff --git a/tests/wpt/web-platform-tests/tools/wave/data/exceptions/invalid_data_exception.py b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/invalid_data_exception.py new file mode 100644 index 00000000000..50c7e8f3727 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/invalid_data_exception.py @@ -0,0 +1,2 @@ +class InvalidDataException(Exception): + pass diff --git a/tests/wpt/web-platform-tests/tools/wave/data/exceptions/not_found_exception.py b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/not_found_exception.py new file mode 100644 index 00000000000..0e573506add --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/not_found_exception.py @@ -0,0 +1,2 @@ +class NotFoundException(Exception): + pass diff --git a/tests/wpt/web-platform-tests/tools/wave/data/exceptions/permission_denied_exception.py b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/permission_denied_exception.py new file mode 100644 index 00000000000..e51660f678a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/exceptions/permission_denied_exception.py @@ -0,0 +1,2 @@ +class PermissionDeniedException(Exception): + pass diff --git a/tests/wpt/web-platform-tests/tools/wave/data/http_polling_client.py b/tests/wpt/web-platform-tests/tools/wave/data/http_polling_client.py new file mode 100644 index 00000000000..740f547c958 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/http_polling_client.py @@ -0,0 +1,11 @@ +from .client import Client + + +class HttpPollingClient(Client): + def __init__(self, session_token, event): + super(HttpPollingClient, self).__init__(session_token) + self.event = event + + def send_message(self, message): + self.message = message + self.event.set() diff --git a/tests/wpt/web-platform-tests/tools/wave/data/session.py b/tests/wpt/web-platform-tests/tools/wave/data/session.py new file mode 100644 index 00000000000..df162fcb082 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/data/session.py @@ -0,0 +1,86 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +from ..testing.test_loader import MANUAL, AUTOMATIC + +PAUSED = "paused" +RUNNING = "running" +COMPLETED = "completed" +ABORTED = "aborted" +PENDING = "pending" +UNKNOWN = "unknown" + + +class Session(object): + def __init__( + self, + token=None, + types=None, + user_agent=None, + labels=None, + tests=None, + pending_tests=None, + running_tests=None, + timeouts=None, + status=None, + test_state=None, + last_completed_test=None, + recent_completed_count=None, + date_started=None, + date_finished=None, + is_public=None, + reference_tokens=None, + browser=None, + webhook_urls=None, + expiration_date=None, + malfunctioning_tests=None + ): + if token is None: + token = "" + self.token = token + if types is None: + types = [AUTOMATIC, MANUAL] + self.types = types + if user_agent is None: + user_agent = "" + self.user_agent = user_agent + if labels is None: + labels = [] + self.labels = labels + if tests is None: + tests = {} + self.tests = tests + if pending_tests is None: + pending_tests = {} + self.pending_tests = pending_tests + if running_tests is None: + running_tests = {} + self.running_tests = running_tests + if timeouts is None: + timeouts = {} + self.timeouts = timeouts + if status is None: + status = UNKNOWN + self.status = status + if test_state is None: + test_state = {} + self.test_state = test_state + self.last_completed_test = last_completed_test + if recent_completed_count is None: + recent_completed_count = 0 + self.recent_completed_count = recent_completed_count + self.date_started = date_started + self.date_finished = date_finished + if is_public is None: + is_public = False + self.is_public = is_public + if reference_tokens is None: + reference_tokens = [] + self.reference_tokens = reference_tokens + self.browser = browser + if webhook_urls is None: + webhook_urls = [] + self.webhook_urls = webhook_urls + self.expiration_date = expiration_date + if malfunctioning_tests is None: + malfunctioning_tests = [] + self.malfunctioning_tests = malfunctioning_tests diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/README.md b/tests/wpt/web-platform-tests/tools/wave/docs/README.md new file mode 100644 index 00000000000..6cf7d397f84 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/README.md @@ -0,0 +1,4 @@ +# WAVE Test Suite Documentation + +- [REST API](./rest-api/README.md) +- [Usage Guide](./usage/usage.md) \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_bottom.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_bottom.jpg new file mode 100644 index 00000000000..85d4bdc3fc8 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_bottom.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_malfunctioning.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_malfunctioning.jpg new file mode 100644 index 00000000000..28f42230d54 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_malfunctioning.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_prev_excluded.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_prev_excluded.jpg new file mode 100644 index 00000000000..c71b34f668f Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_prev_excluded.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_raw.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_raw.jpg new file mode 100644 index 00000000000..f1428f313dc Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_exclude_add_raw.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_top.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_top.jpg new file mode 100644 index 00000000000..93b6522bc7c Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/configuration_page_top.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/landing_page.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/landing_page.jpg new file mode 100644 index 00000000000..c032a7b2914 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/landing_page.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions.jpg new file mode 100644 index 00000000000..642a009d4a5 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_filtered.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_filtered.jpg new file mode 100644 index 00000000000..266a5c11590 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_filtered.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_pinned_recent.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_pinned_recent.jpg new file mode 100644 index 00000000000..fb92a47bf47 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_sessions_pinned_recent.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_top.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_top.jpg new file mode 100644 index 00000000000..860272796a6 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/overview_page_top.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results.jpg new file mode 100644 index 00000000000..e0e2314a78e Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results_export.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results_export.jpg new file mode 100644 index 00000000000..c85ce980fe3 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_api_results_export.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_bottom.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_bottom.jpg new file mode 100644 index 00000000000..60244a8e46d Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_bottom.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_last_timed_out.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_last_timed_out.jpg new file mode 100644 index 00000000000..bb63bd4d51a Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_last_timed_out.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_malfunctioning_list.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_malfunctioning_list.jpg new file mode 100644 index 00000000000..fcd6b370fd2 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_malfunctioning_list.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_top.jpg b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_top.jpg new file mode 100644 index 00000000000..3d0f876c7b9 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/docs/res/results_page_top.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/README.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/README.md new file mode 100644 index 00000000000..73c24f8ac52 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/README.md @@ -0,0 +1,54 @@ +# REST API - [WAVE Test Suite](../README.md) + +The REST API allows the WAVE server to be integrated into other systems. Every +call must be preceded with a namespace or web root, which is omitted in this +documentation. The default web root is `/_wave`, which can be changed in the +config.json using the keyword `web_root`. + +## Sessions API + +| Name | Description | +| ---------------------------------------------- | ---------------------------------------------------- | +| [`create`](./sessions-api/create.md) | Creates a new test session. | +| [`read`](./sessions-api/read.md) | Reads a sessions configuration. | +| [`read public`](./sessions-api/read-public.md) | Reads all public sessions tokens. | +| [`update`](./sessions-api/update.md) | Updates a session configuration. | +| [`delete`](./sessions-api/delete.md) | Deletes a test session. | +| [`status`](./sessions-api/status.md) | Reads the status and progress of a session. | +| [`start`](./sessions-api/control.md#start) | Starts a test session. | +| [`stop`](./sessions-api/control.md#stop) | Stops a test session. | +| [`pause`](./sessions-api/control.md#pause) | Pauses a test session. | +| [`find`](./sessions-api/find.md) | Finds a session token by providing a token fragment. | +| [`labels`](./sessions-api/labels.md) | Attach labels to sessions for organization purposes. | +| [`events`](./sessions-api/events.md) | Register for sessions specific events. | + +## Tests API + +| Name | Description | +| --------------------------------------------------------------- | ------------------------------------------------------ | +| [`read all`](./tests-api/read-all.md) | Reads all tests available. | +| [`read session`](./tests-api/read-session.md) | Reads all tests that are part of a session. | +| [`read next`](./tests-api/read-next.md) | Reads the next test to run in a session. | +| [`read last completed`](./tests-api/read-last-completed.md) | Reads the last completed tests of a session. | +| [`read malfunctioning`](./tests-api/read-malfunctioning.md) | Reads the list of malfunctioning tests of a session. | +| [`update malfunctioning`](./tests-api/update-malfunctioning.md) | Updates the list of malfunctioning tests of a session. | +| [`read available apis`](./tests-api/read-available-apis.md) | Reads all available APIs names and paths. | + +## Results API + +| Name | Description | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| [`create`](./results-api/create.md) | Create a new test result for a test in a session. | +| [`read`](./results-api/read.md) | Read all test results of a session. | +| [`read compact`](./results-api/read-compact.md) | Read the number of passed, failed, timed out and not run tests of a session. | +| [`config`](./results-api/config.md) | Read what features of the results API are enabled. | +| [`import`](./results-api/import.md) | Import session results. | +| [`import enabled`](./results-api/import.md#2-import-enabled) | Check whether or not the import feature is enabled. | +| [`download`](./results-api/download.md#1-download) | Download all session results to import into other WMATS instance. | +| [`download api`](./results-api/download.md#2-download-api) | Download all results of an API. | +| [`download all apis`](./results-api/download.md#3-download-all-apis) | Download all results of all APIs. | +| [`view report`](./results-api/download.md#4-download-report) | View the WPT report of an API of a session. | +| [`view multi report`](./results-api/download.md#5-download-multi-report) | View the WPT report of an API of multiple sessions. | +| [`download overview`](./results-api/download.md#6-download-overview) | Download an overview of results of all APIs of a session. | +| [`view report`](./results-api/view.md#1-view-report) | Read an url to a hosted version of a WPT report for an API of a session. | +| [`view multi report`](./results-api/view.md#2-view-multi-report) | Read an url to a hosted version of a WPT report for an API of multiple session. | diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/config.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/config.md new file mode 100644 index 00000000000..a60485dadc7 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/config.md @@ -0,0 +1,34 @@ +# `config` - [Results API](../README.md#results-api) + +The `config` method is used to determine what features of the results API are +enabled. Features that can be enabled or disabled are the +[`import`](./import.md) method and the generation of reports and therefore +[`download and view`](./download.md) methods. + +## HTTP Request + +`GET /api/results/config` + +## Response + +```json +{ + "import_enabled": "Boolean", + "reports_enabled": "Boolean" +} +``` + +## Example + +**Request:** + +`GET /api/results/config` + +**Response:** + +```json +{ + "import_enabled": false, + "reports_enabled": true +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/create.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/create.md new file mode 100644 index 00000000000..5839702eda1 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/create.md @@ -0,0 +1,65 @@ +# `create` - [Results API](../README.md#results-api) + +The `create` method of the results API creates a test result for a given test of a test session. + +## HTTP Request + +`POST /api/results/` + +## Request Payload + +```json +{ + "test": "String", + "status": "Enum['OK', 'ERROR', 'TIMEOUT', 'NOT_RUN']", + "message": "String", + "subtests": [ + { + "name": "String", + "status": "Enum['PASS', 'FAIL', 'TIMEOUT', 'NOT_RUN']", + "message": "String" + } + ] +} +``` + +- **test** specifies the test to create the result for. +- **status** specifies the overall status of the test. It does not represent a result, but rather if the contained tests were executed as intended or if something went wrong running the test. + - **OK**: All tests were executed without problems. + - **ERROR**: There was an error running one or multiple tests. + - **TIMEOUT**: It took too long for the tests to execute. + - **NOT_RUN**: This test was skipped. +- **message** contains the reason for the overall status. If the status is `OK` the message should be `null`. +- **subtests** contains the actual results of the tests executed in this file. + - **name**: The name of the test. + - **status**: The status of the result: + - **PASS**: The test was executed successfully. + - **FAIL**: The test did not meet at least one assertion. + - **TIMEOUT**: It took too long for this test to execute. + - **NOT_RUN**: This test was skipped. + - **message** contains the reason for the tests failure. + +## Example + +**Request:** + +`POST /api/results/d89bcc00-c35b-11e9-8bb7-9e3d7595d40c` + +```json +{ + "test": "/apiOne/test/one.html", + "status": "OK", + "message": null, + "subtests": [ + { + "name": "Value should be X", + "status": "FAIL", + "message": "Expected value to be X but got Y" + } + ] +} +``` + +**Response:** + +`200 OK` \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/download.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/download.md new file mode 100644 index 00000000000..f752dfaa66f --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/download.md @@ -0,0 +1,127 @@ +# Downloading and viewing results and reports - [Results API](../README.md#results-api) + +There are multiple methods to download or view reports generated by the WPT +Report tool or just the plain json results with the structure as described in +the [`create`](./create.md) method of the results API. + +## 1. `download` + +Downloads all results of a session as ZIP, which other instances of the WMAS +Test Suite can import. + +### HTTP Request + +`GET /api/results//export` + +### Example + +`GET /api/results/f63700a0-c35f-11e9-af33-9e0d4c1f1370/export` + +## 2. `download api` + +Downloads all results of a single API in one json file. + +### HTTP Request + +`GET /api/results///json` + +### File Structure + +```json +{ + "results": [ + { + "test": "String", + "status": "Enum['OK', 'ERROR', 'TIMEOUT', 'NOT_RUN']", + "message": "String", + "subtests": [ + { + "name": "String", + "status": "Enum['PASS', 'FAIL', 'TIMEOUT', 'NOT_RUN']", + "message": "String" + } + ] + } + ] +} +``` + +Results are structured as explained in the [`create`](./create.md) method of the results API. + +### Example + +`GET /api/results/f63700a0-c35f-11e9-af33-9e0d4c1f1370/apiOne/json` + +## 3. `download all apis` + +Downloads all results of all APIs of a session as zip file containing one json file per API. + +### HTTP Request + +`GET /api/results//json` + +### File Structure + +There is one json file per API, each structured as described in the [`download api`](#download-api) method. + +### Example + +`GET /api/results/f63700a0-c35f-11e9-af33-9e0d4c1f1370/json` + +## 4. `view report` + +Returns a URL to a report of an API of a session, generated by the WPT Report tool, which is a static HTML page. + +### HTTP Request + +`GET /api/results///reporturl` + +### Example + +`GET /api/results/f63700a0-c35f-11e9-af33-9e0d4c1f1370/apiOne/reporturl` + +**Response** + +```json +{ + "uri": "/results/8f7f2fdc-62eb-11ea-8615-b8ca3a7b18ad/2dcontext/all.html" +} +``` + +## 5. `view multi report` + +Returns a URL to a report of an API of multiple session, generated by the WPT Report tool, which is a static HTML page. + +### HTTP Request + +`GET /api/results//reporturl` + +### Query Parameters + +| Parameter | Description | Default | Example | +| --------- | ------------------------------------------------------------ | ------- | -------------------------------- | +| `tokens` | Comma separated list of tokens to create a multi report for. | none | `tokens=token_a,token_b,token_c` | + +### Example + +`GET /api/results/apiOne/reporturl?tokens=8f7f2fdc-62eb-11ea-8615-b8ca3a7b18ad,990b4734-62eb-11ea-a9a5-b8ca3a7b18ad` + +**Response** + +```json +{ + "uri": "/results/comparison-8f7f2fdc-990b473401488e04/reporturl/all.html" +} +``` + +## 6. `download overview` + +Downloads a zip file containing an overview for all APIs results of a session as a static HTML page. + +### HTTP Request + +`GET /api/results//overview` + +### Example + +`GET /api/results/f63700a0-c35f-11e9-af33-9e0d4c1f1370/overview` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/import.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/import.md new file mode 100644 index 00000000000..75026768f87 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/import.md @@ -0,0 +1,45 @@ +# Import results - [Results API](../README.md#results-api) + +If enabled, the WMAS Test Suite can import results exported by any arbitrary other instance. + +## 1. `import` + +Import a session's results from a ZIP file. + +### HTTP Request + +`POST /api/results/import` + +### HTTP Response + +If successful, the server responds with the token of the imported session: + +```json +{ + "token": "String" +} +``` + +However, if an error occured, the server responds the error message: + +```json +{ + "error": "String" +} +``` + +## 2. `import enabled` + +To check whether or not the import features is enabled, the `import enabled` method returns the state as JSON. + +### HTTP Request + +`GET /api/results/import` + +### Response + +```json +{ + "enabled": "Boolean" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read-compact.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read-compact.md new file mode 100644 index 00000000000..55b6f41d4ba --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read-compact.md @@ -0,0 +1,59 @@ +# `read compact` - [Results API](../README.md#results-api) + +The `read compact` method of the results API returns the number of passed, failed, timed out and not run tests per API of a session. + +## HTTP Request + +`GET /api/results//compact` + +## Response Payload + +```json +{ + "": { + "pass": "Integer", + "fail": "Integer", + "timeout": "Integer", + "not_run": "Integer", + "total": "Integer", + "complete": "Integer" + } +} +``` + +## Example + +**Request:** + +`GET /api/results/620bbf70-c35e-11e9-bf9c-742c02629054/compact` + +**Response:** + +```json +{ + "apiOne": { + "pass": 311, + "fail": 59, + "timeout": 23, + "not_run": 20, + "total": 481, + "complete": 413 + }, + "apiTwo": { + "pass": 548, + "fail": 129, + "timeout": 53, + "not_run": 36, + "total": 766, + "complete": 766 + }, + "apiThree": { + "pass": 349, + "fail": 45, + "timeout": 14, + "not_run": 9, + "total": 523, + "complete": 417 + } +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read.md new file mode 100644 index 00000000000..66894e69ee9 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/read.md @@ -0,0 +1,63 @@ +# `read` - [Results API](../README.md#results-api) + +The `read` method of the results API returns all available results of a session, grouped by API. It is possible to filter the results to return by test directory or file. + +## HTTP Request + +`GET /api/results/` + +## Query Parameters + +| Parameter | Description | Default | Example | +| --------- | ------------------------------ | ------- | --------------------------- | +| `path` | Path of test directory or file | `/` | `path=/apiOne/test/sub/dir` | + +## Response Payload + +```json +{ + "": [ + { + "test": "String", + "status": "Enum['OK', 'ERROR', 'TIMEOUT', 'NOT_RUN']", + "message": "String", + "subtests": [ + { + "name": "String", + "status": "Enum['PASS', 'FAIL', 'TIMEOUT', 'NOT_RUN']", + "message": "String" + } + ] + } + ] +} +``` + +Arrays of results grouped by their respective APIs. Structure of results is the same as described in the [`create`](./create.md) method of the results API. + +## Example + +**Request:** + +`GET /api/results/974c84e0-c35d-11e9-8f8d-47bb5bb0037d?path=/apiOne/test/one.html` + +**Response:** + +```json +{ + "apiOne": [ + { + "test": "/apiOne/test/one.html", + "status": "OK", + "message": null, + "subtests": [ + { + "name": "Value should be X", + "status": "FAIL", + "message": "Expected value to be X but got Y" + } + ] + } + ] +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/view.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/view.md new file mode 100644 index 00000000000..5b60d2ccf2e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/results-api/view.md @@ -0,0 +1,61 @@ +# Viewing Reports - [Results API](../README.md#results-api) + +It is possible to view the reports generated by the WPT Report tool directly in the browser using a version of the report that is hosted by the WAVE server. The methods listed here return urls to those hosted reports. + +## 1. `view report` + +Returns a URL to a report for an API of a single session, generated by the WPT Report tool. + +### HTTP Request + +`GET /api/results///reporturl` + +### Response Payload + +```json +{ + "uri": "String" +} +``` + +### Example + +**Request:** + +`GET /api/results/d9caaae0-c362-11e9-943f-eedb305f22f6/apiOne/reporturl` + +**Response:** + +```json +{ + "uri": "/results/d9caaae0-c362-11e9-943f-eedb305f22f6/apiOne/all.html" +} +``` + +## 2. `view multi report` + +Returns a URL to a report for an API of multiple session, generated by the WPT Report tool. + +### HTTP Request + +`GET /api/results//reporturl` + +### Query Parameters + +| Parameter | Description | Default | Example | +| --------- | ------------------------------------------------------------ | ------- | -------------------------------- | +| `tokens` | Comma separated list of tokens to create a multi report for. | none | `tokens=token_a,token_b,token_c` | + +### Example + +**Request:** + +`GET /api/results/apiOne/reporturl?tokens=ce2dc080-c283-11e9-b4d6-e046513784c2,cd922410-c344-11e9-858f-9063f6dd878f` + +**Response:** + +```json +{ + "uri": "/results/comparison-cd922410-ce2dc080-1709d631/apiOne/all.html" +} +``` \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/control.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/control.md new file mode 100644 index 00000000000..c439c118f85 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/control.md @@ -0,0 +1,25 @@ +# Controlling Sessions - [Sessions API](../README.md#sessions-api) + +It is possible to control the execution of tests on the device under test using the session APIs control methods. They change the status of a session and trigger the device under test to fetch a new url to change location to. Depending on the current status of the session this can be a test or a static page showing information about the current status. + +## `start` +The `start` method changes the status of a session from either `PENDING` or `PAUSED` to `RUNNING` and triggers the device under test to execute tests when resuming a paused session. + +### HTTP Request + +`POST /api/sessions//start` + +## `pause` +The `pause` method changes the status of a session from `RUNNING` to `PAUSED` and pauses the execution of tests on the device under test. + +### HTTP Request + +`POST /api/sessions//pause` + +## `stop` +The `stop` method finishes a session early by skipping all pending tests, causing a change of the status to `ABORTED`. It is not possible to undo this action and can only be performed on sessions that are not `ABORTED` or `COMPLETED`. + +### HTTP Request + +`POST /api/sessions//stop` + diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/create.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/create.md new file mode 100644 index 00000000000..eaf00ac1669 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/create.md @@ -0,0 +1,101 @@ +# `create` - [Sessions API](../README.md#sessions-api) + +The `create` method of the sessions API creates a new session. If provided with an configuration it creates a session accordingly. If no configuration is provided it uses default values. It returns the session token of the newly created session, which is the unique identifier of sessions. While a session has the status `PENDING` it is possible to modify the configuration using the [`update`](./update.md) method of the sessions API. As it is required to create the session from the device under test, this is really helpful, since it allows to configure the session using a second device. + +## HTTP Request + +`POST /api/sessions` + +## Request Payload + +```json +{ + "tests": { + "include": "Array", + "exclude": "Array" + }, + "types": "Enum['automatic', 'manual']", + "timeouts": { + "automatic": "Integer", + "manual": "Integer", + "": "Integer" + }, + "reference_tokens": "Array", + "labels": "Array" +} +``` + +- **tests** specifies the tests of the session: + - **include** specifies what tests should be selected from all available tests. Can be a path to a test file or directory. + - **exclude** specifies what tests should be removed from the included tests. Can be a path to a test file or directory. +- **types** what types of tests should be included. Possible values: + - **automatic** tests are tests that execute without user interaction. + - **manual** tests are tests that require user interaction. +- **timeouts** specifies the time to wait for a test to finish in milliseconds. + - **automatic**: Sets the default timeout for all automatic tests. + - **manual**: Sets the default timeout for all manual tests. + - **custom test paths**: Set the timeout for a test file or directory by putting the path with all dots removed as the key. +- **reference_tokens** specifies a set of completed sessions that is used to filter out all tests that have not passed in all those sessions from the session that is going to be created. +- **labels** specifies the initial set of labels for the session. + +### Default + +```json +{ + "tests": { + "include": ["/"], + "exclude": [] + }, + "types": ["automatic", "manual"], + "timeouts": { + "automatic": 60000, + "manual": 300000 + }, + "reference_tokens": [], + "labels": [] +} +``` + +## Response Payload + +If successful, the token of the new session is returned. + +```json +{ + "token": "String" +} +``` + +## Example + +**Request:** + +`POST /api/sessions` + +```json +{ + "tests": { + "include": ["/apiOne", "/apiTwo/sub"], + "exclude": ["/apiOne/specials"] + }, + "types": ["automatic"], + "timeouts": { + "automatic": 70000, + "/apiOne/example/dir": 30000, + "/apiOne/example/filehtml": 45000 + }, + "reference_tokens": [ + "ce2dc080-c283-11e9-b4d6-e046513784c2", + "430f47d0-c283-11e9-8776-fcbc36b81035" + ], + "labels": ["label1", "label2", "label3"] +} +``` + +**Response:** + +```json +{ + "token": "6fdbd1a0-c339-11e9-b775-6d49dd567772" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/delete.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/delete.md new file mode 100644 index 00000000000..f11d86035bf --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/delete.md @@ -0,0 +1,25 @@ +# `delete` - [Sessions API](../README.md#sessions-api) + +The `delete` method of the sessions API is used to delete a session and single results associated with it. However artifacts like generated reports or JSON files containing results of a whole API remain, therefore urls to those resources are still working. + +## HTTP Request + +`DELETE /api/sessions/` + +## Example + +**Request:** + +`DELETE /api/sessions/1592b880-c339-11e9-b414-61af09c491b1` + +**Response:** + +`200 OK` + +**Request:** + +`GET /api/sessions/1592b880-c339-11e9-b414-61af09c491b1` + +**Response:** + +`404 NOT FOUND` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/events.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/events.md new file mode 100644 index 00000000000..e2148b1dd36 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/events.md @@ -0,0 +1,34 @@ +# `events` - [Sessions API](../README.md#sessions-api) + +Listen for session specific events by registering on the `events` endpoint using HTTP long polling. + +## HTTP Request + +`GET /api/sessions//events` + +## Response Payload + +```json +{ + "type": "String", + "data": "String" +} +``` + +- **type**: the type of event that occurred. +- **data**: the actual payload of the event + +## Example + +**Request** + +`GET /api/sessions/6fdbd1a0-c339-11e9-b775-6d49dd567772/events` + +**Response** + +```json +{ + "type": "status", + "data": "paused" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/find.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/find.md new file mode 100644 index 00000000000..3ffc6f58c48 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/find.md @@ -0,0 +1,29 @@ +# `find` - [Sessions API](../README.md#sessions-api) + +The `find` method of the sessions API searches for a session token using a provided token fragment, which is the beginning of a session token with at least 8 characters. Due to data protection, it is not possible to find multiple tokens using one fragment. If the server finds more than one session token, it returns none. In this case more characters need to be added to the fragment, until it matches only one session token. + +## HTTP Request + +`GET /api/sessions/` + +## Response Payload + +```json +{ + "token": "String" +} +``` + +### Example + +**Request:** + +`GET /api/sessions/afd4ecb0` + +**Response:** + +```json +{ + "token": "afd4ecb0-c339-11e9-b66c-eca76c2bea9c" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/labels.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/labels.md new file mode 100644 index 00000000000..00a8defd986 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/labels.md @@ -0,0 +1,75 @@ +# `labels` - [Sessions API](../README.md#sessions-api) + +The `labels` methods of the sessions API allow for better organization of sessions. + +## Read labels + +Reads all labels of a session. + +### HTTP Request + +`GET /api/sessions//labels` + +### Response Payload + +```json +"Array" +``` + +#### Example + +**Request:** + +`GET /api/sessions/afd4ecb0-c339-11e9-b66c-eca76c2bea9c/labels` + +**Response:** + +```json +["label1", "label2", "label3"] +``` + +## Update labels + +Update all labels of a session. + +### HTTP Request + +`PUT /api/sessions//labels` + +### Request Payload + +```json +"Array" +``` + +The array of labels provided in the request payload will replace all existing labels of the session. + +#### Example + +**Request:** + +`GET /api/sessions/afd4ecb0-c339-11e9-b66c-eca76c2bea9c/labels` + +**Response:** + +```json +["label1", "label2", "label3"] +``` + +**Request:** + +`PUT /api/sessions/afd4ecb0-c339-11e9-b66c-eca76c2bea9c/labels` + +```json +["label4", "label5"] +``` + +**Request:** + +`GET /api/sessions/afd4ecb0-c339-11e9-b66c-eca76c2bea9c/labels` + +**Response:** + +```json +["label4", "label5"] +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read-public.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read-public.md new file mode 100644 index 00000000000..3e0e9089c4f --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read-public.md @@ -0,0 +1,30 @@ +# `read public` - [Sessions API](../README.md#sessions-api) + +The `read public` method of the sessions API fetches a list of all sessions that are publicly available. It is not possible to delete those sessions using the user interface or the REST API. Currently there is no way to change is-public-state of a session using the API. + +## HTTP Request + +`GET /api/sessions/public` + +## Response Payload + +```json +"Array" +``` + +## Example + +**Request:** + +`GET /api/sessions/public` + +**Response:** + +```json +[ + "bb7aafa0-6a92-11e9-8ec2-04f58dad2e4f", + "caf823e0-6a92-11e9-b732-3188d0065ebc", + "a50c6db0-6a94-11e9-8d1b-e23fc4555885", + "b2924d20-6a93-11e9-98b4-a11fb92a6d1c" +] +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read.md new file mode 100644 index 00000000000..da4b57377a6 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/read.md @@ -0,0 +1,84 @@ +# `read` - [Sessions API](../README.md#sessions-api) + +The `read` method of the sessions API fetches the configuration of a session, including values that can not be set by the user, but are created by the server upon creation. + +## HTTP Request + +`GET /api/sessions/` + +## Response Payload + +```json +{ + "token": "String", + "tests": { + "include": "Array", + "exclude": "Array" + }, + "types": "Enum['automatic', 'manual']", + "timeouts": { + "automatic": "Integer", + "manual": "Integer", + "": "Integer" + }, + "reference_tokens": "Array", + "user_agent": "String", + "browser": { + "name": "String", + "version": "String" + }, + "is_public": "Boolean" +} +``` + +- **token** is the unique identifier of the session. +- **tests** specifies the tests of the session: + - **include** specifies what tests should be selected from all available tests. Can be a path to a test file or directory. + - **exclude** specifies what tests should be removed from the included tests. Can be a path to a test file or directory. +- **types** what types of tests should be included. Possible values: + - **automatic** tests are tests that execute without user interaction. + - **manual** tests are tests that require user interaction. +- **timeouts** specifies the time to wait for a test to finish in milliseconds. + - **automatic**: Sets the default timeout for all automatic tests. + - **manual**: Sets the default timeout for all manual tests. + - **custom test paths**: Set the timeout for a test file or directory by putting the path with all dots removed as the key. +- **reference_tokens** specifies a set of completed sessions that is used to filter out all tests that have not passed in all those sessions from the session that is going to be created. +- **user_agent** is the user agent string of the request that created the session. The request to create the session should performed by the device under test. +- **browser** holds information about the browser, parsed from the user agent. + - **name**: The name of the browser. + - **version**: The version numbers of the browser. +- **is_public** defines whether or not the session is listed when fetching the list of public session using [`read public`](./read-public.md). + +## Example + +**Request:** + +`GET /api/sessions/47a6fa50-c331-11e9-8709-a8eaa0ecfd0e` + +**Response:** + +```json +{ + "token": "47a6fa50-c331-11e9-8709-a8eaa0ecfd0e", + "tests": { + "include": ["/apiOne", "/apiTwo/sub"], + "exclude": ["/apiOne/specials"] + }, + "types": ["automatic"], + "timeouts": { + "automatic": 70000, + "/apiOne/example/dir": 30000, + "/apiOne/example/filehtml": 45000 + }, + "reference_tokens": [ + "ce2dc080-c283-11e9-b4d6-e046513784c2", + "430f47d0-c283-11e9-8776-fcbc36b81035" + ], + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/76.0.3809.100 Chrome/76.0.3809.100 Safari/537.36", + "browser": { + "name": "Chromium", + "version": "76" + }, + "is_public": "false" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/status.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/status.md new file mode 100644 index 00000000000..4f50831ae84 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/status.md @@ -0,0 +1,48 @@ +# `status` - [Sessions API](../README.md#sessions-api) + +The `status` method of the results API returns information about a sessions current status and progress. + +## HTTP Request + +`GET /api/sessions//status` + +## Response Payload + +```json +{ + "token": "String", + "status": "Enum['pending', 'running', 'paused', 'completed', 'aborted']", + "date_started": "String", + "date_finished": "String", + "expiration_date": "String" +} +``` + +- **token** contains the token of the session corresponding to this status. +- **status** specifies the current status of the session: + - **pending**: The session was created, can receive updates, however cannot execute tests. + - **running**: The session currently executes tests. + - **paused**: The execution of tests in this session is currently paused. + - **completed**: All tests files include in this session were executed and have a result. + - **aborted**: The session was finished before all tests were executed. +- **date_started** contains the time the status changed from `PENDING` to `RUNNING` in unix epoch time milliseconds. +- **date_finished** contains the time the status changed to either `COMPLETED` or `ABORTED` in unix epoch time milliseconds. +- **expiration_date** contains the time at which the sessions will be deleted + +## Example + +**Request:** + +`GET /api/sessions/d9caaae0-c362-11e9-943f-eedb305f22f6/status` + +**Response:** + +```json +{ + "token": "d9caaae0-c362-11e9-943f-eedb305f22f6", + "status": "running", + "date_started": "1567606879230", + "date_finished": null, + "expiration_date": "1567607179230" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/update.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/update.md new file mode 100644 index 00000000000..3817c115934 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/sessions-api/update.md @@ -0,0 +1,102 @@ +# `update` - [Sessions API](../README.md#sessions-api) + +The `update` method of the sessions API makes it possible to modify a sessions configuration while its status is `PENDING`. This can be used to configure the session on a second device, rather than on the device under test. + +## HTTP Request + +`PUT /api/sessions/` + +## Request Payload + +The request payload is the same as in the [`create`](./sessions-api/create.md) method of the sessions API. Only keys that are an inherent part of the configuration will stay the same if not specified in the `update` payload. All others will be deleted if not included. + +## Example + +**Request:** + +`GET /api/sessions/47a6fa50-c331-11e9-8709-a8eaa0ecfd0e` + +**Response:** + +```json +{ + "token": "47a6fa50-c331-11e9-8709-a8eaa0ecfd0e", + "tests": { + "include": ["/apiOne", "/apiTwo/sub"], + "exclude": ["/apiOne/specials"] + }, + "types": ["automatic"], + "timeouts": { + "automatic": 70000, + "/apiOne/example/dir": 30000, + "/apiOne/example/filehtml": 45000 + }, + "reference_tokens": [ + "ce2dc080-c283-11e9-b4d6-e046513784c2", + "430f47d0-c283-11e9-8776-fcbc36b81035" + ], + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/76.0.3809.100 Chrome/76.0.3809.100 Safari/537.36", + "browser": { + "name": "Chromium", + "version": "76" + }, + "is_public": "false", + "labels": [] +} +``` + +**Request:** + +`PUT /api/sessions/47a6fa50-c331-11e9-8709-a8eaa0ecfd0e` + +```json +{ + "tests": { + "include": ["/apiOne", "/apiThree"] + }, + "timeouts": { + "automatic": 60000 + }, + "reference_tokens": [ + "bb7aafa0-6a92-11e9-8ec2-04f58dad2e4f", + "a50c6db0-6a94-11e9-8d1b-e23fc4555885" + ], + "labels": ["label1", "label2"] +} +``` + +**Response:** + +`200 OK` + +**Request:** + +`GET /api/sessions/47a6fa50-c331-11e9-8709-a8eaa0ecfd0e` + +**Response:** + +```json +{ + "token": "47a6fa50-c331-11e9-8709-a8eaa0ecfd0e", + "tests": { + "include": ["/apiOne", "/apiThree"], + "exclude": ["/apiOne/specials"] + }, + "types": ["automatic"], + "timeouts": { + "automatic": 60000, + "manual": 360000 + }, + "reference_tokens": [ + "bb7aafa0-6a92-11e9-8ec2-04f58dad2e4f", + "a50c6db0-6a94-11e9-8d1b-e23fc4555885" + ], + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/76.0.3809.100 Chrome/76.0.3809.100 Safari/537.36", + "browser": { + "name": "Chromium", + "version": "76" + }, + "is_public": "false", + "labels": ["label1", "label2"] +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-all.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-all.md new file mode 100644 index 00000000000..8480981b669 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-all.md @@ -0,0 +1,43 @@ +# `read all` - [Tests API](../README.md#tests-api) + +The `read all` method of the tests API fetches all tests available to include into a test session. + +## HTTP Request + +`GET /api/tests` + +## Response Payload + +```json +{ + "": "Array" +} +``` + +## Example + +**Request:** + +`GET /api/tests` + +**Response:** + +```json +{ + "apiOne": [ + "/apiOne/test/one.html", + "/apiOne/test/two.html", + "/apiOne/test/three.html" + ], + "apiTwo": [ + "/apiTwo/test/one.html", + "/apiTwo/test/two.html", + "/apiTWo/test/three.html" + ], + "apiThree": [ + "/apiThree/test/one.html", + "/apiThree/test/two.html", + "/apiThree/test/three.html" + ] +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-available-apis.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-available-apis.md new file mode 100644 index 00000000000..d197c2c21a9 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-available-apis.md @@ -0,0 +1,43 @@ +# `read available apis` - [Tests API](../README.md#tests-api) + +The `read available apis` method return a list of all web APIs that the DUT +can be tested for. It returns the human readable API name, as well as the +directory name under which all corresponding tests reside. + +## HTTP Request + +`GET /api/tests/apis` + +## Response Payload + +```json +[ + { + "path": "String", + "name": "String" + }, + ... +] +``` + +## Example + +**Request:** + +`GET /api/tests/apis` + +**Response:** + +```json +[ + { + "path": "/2dcontext", + "name": "2D Context" + }, + { + "path": "/media-source", + "name": "Media Source" + }, + ... +] +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-last-completed.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-last-completed.md new file mode 100644 index 00000000000..1c1f87a7263 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-last-completed.md @@ -0,0 +1,47 @@ +# `read last completed` - [Tests API](../README.md#tests-api) + +The `read last completed` method of the tests API returns a list of test files, which most recently finished and have a result. The files are grouped by the status their respective result had. + +## HTTP Request + +`GET /api/tests//last_completed` + +## Query Parameters + +| Parameter | Desciption | Default | Example | +| --------- | ------------------------------------------------------------------------------------------------------------------------- | ------- | --------------------- | +| `count` | Number of files per status to return | 5 | `count=5` | +| `status` | The status the files results must have. Comma separated list. Possible values: `all`, `pass`, `fail` and `timeout` | `all` | `status=timeout,pass` | + +## Response Payload + +```json +{ + "pass": "Array", + "fail": "Array", + "timeout": "Array" +} +``` + +## Example + +**Request:** + +`GET /api/tests/7dafeec0-c351-11e9-84c5-3d1ede2e7d2e/last_completed?count=3&status=fail,timeout` + +**Response:** + +```json +{ + "fail": [ + "/apiTwo/test/four.html", + "/apiOne/test/twentyfour.html", + "/apiOne/test/nineteen.html" + ], + "timeout": [ + "/apiFive/test/eight.html", + "/apiThree/test/five.html", + "/apiThree/test/two.html" + ] +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-malfunctioning.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-malfunctioning.md new file mode 100644 index 00000000000..755b2f78972 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-malfunctioning.md @@ -0,0 +1,30 @@ +# `read malfunctioning` - [Tests API](../README.md#tests-api) + +The `read malfunctioning` method of the tests API returns a list of test files, which were flagged as not working properly in a specific session. This is useful to [add them to the exclude list](../../usage/excluding-tests.md) of further test sessions. + +## HTTP Request + +`GET /api/tests//malfunctioning` + +## Response Payload + +```json +"Array" +``` + +## Example + +**Request:** + +`GET /api/tests/7dafeec0-c351-11e9-84c5-3d1ede2e7d2e/malfunctioning` + +**Response:** + +```json +[ + "/apiOne/test/one.html", + "/apiOne/test/five.html", + "/apiThree/test/two.html", + "/apiThree/test/twenty.html" +] +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-next.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-next.md new file mode 100644 index 00000000000..c10ba81a124 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-next.md @@ -0,0 +1,29 @@ +# `read next` - [Tests API](../README.md#tests-api) + +The `read next` method of the tests API returns the next test of a test session, that is due to be executed. If the sessions status is not `RUNNING` it returns a static page containing information about the session and its current status. + +## HTTP Request + +`GET /api/tests//next` + +## Response Payload + +```json +{ + "next_test": "String" +} +``` + +## Example + +**Request:** + +`GET /api/tests/d6667670-c350-11e9-b504-4ac471cdd99d/next` + +**Response:** + +```json +{ + "next_test": "http://web-platform.test:8000/apiOne/test/one.html?&token=d6667670-c350-11e9-b504-4ac471cdd99d&timeout=60000" +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-session.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-session.md new file mode 100644 index 00000000000..59344d5e68b --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/read-session.md @@ -0,0 +1,61 @@ +# `read session` - [Tests API](../README.md#tests-api) + +The `read session` method of the tests API fetches all tests contained in a test session grouped by their status. + +## HTTP Request + +`GET /api/tests/` + +## Response Payload + +```json +{ + "token": "String", + "pending_tests": { + "": "Array" + }, + "running_tests": { + "": "Array" + }, + "completed_tests": { + "": "Array" + } +} +``` + +- **pending_tests** are tests that have yet to be executed. +- **running_tests** are tests that are currently executed by the device under test. Although only one test at a time is executed, test that time out or fail to send a result may still wait for the time out to occur. In this case there are multiple tests in this list. +- **completed_tests** are tests that are finished and have a result. + +## Example + +**Request:** + +`GET /api/tests/cd922410-c344-11e9-858f-9063f6dd878f` + +**Response:** + +```json +{ + "token": "cd922410-c344-11e9-858f-9063f6dd878f", + "pending_tests": { + "apiTwo": ["/apiTwo/test/three.html"], + "apiThree": [ + "/apiThree/test/one.html", + "/apiThree/test/two.html", + "/apiThree/test/three.html" + ] + }, + "running_tests": { + "apiTwo": ["/apiTwo/test/two.html"] + }, + "completed_tests": { + "apiOne": [ + "/apiOne/test/one.html", + "/apiOne/test/two.html", + "/apiOne/test/three.html" + ], + "apiTwo": ["/apiTwo/test/one.html"] + } +} +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/update-malfunctioning.md b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/update-malfunctioning.md new file mode 100644 index 00000000000..327d1c14d1e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/rest-api/tests-api/update-malfunctioning.md @@ -0,0 +1,56 @@ +# `update malfunctioning` - [Tests API](../README.md#tests-api) + +The `update malfunctioning` method of the tests API sets the list of test files, that are flagged as not working properly in a specific session. It replaces the existing list with the new provided list. + +## HTTP Request + +`PUT /api/tests//malfunctioning` + +## Request Payload + +```json +"Array" +``` + +## Example + +**Request:** + +`GET /api/tests/7dafeec0-c351-11e9-84c5-3d1ede2e7d2e/malfunctioning` + +**Response:** + +```json +[ + "/apiOne/test/one.html", + "/apiOne/test/five.html", + "/apiThree/test/two.html", + "/apiThree/test/twenty.html" +] +``` + +**Request:** + +`PUT /api/tests/7dafeec0-c351-11e9-84c5-3d1ede2e7d2e/malfunctioning` + +```json +[ + "/apiOne/test/three.html", + "/apiOne/test/eight.html", + "/apiThree/test/one.html" +] +``` + +**Request:** + +`GET /api/tests/7dafeec0-c351-11e9-84c5-3d1ede2e7d2e/malfunctioning` + +**Response:** + +```json +[ + "/apiOne/test/three.html", + "/apiOne/test/eight.html", + "/apiThree/test/one.html" +] +``` diff --git a/tests/wpt/web-platform-tests/tools/wave/docs/usage/usage.md b/tests/wpt/web-platform-tests/tools/wave/docs/usage/usage.md new file mode 100644 index 00000000000..025eeae424e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/docs/usage/usage.md @@ -0,0 +1,224 @@ +# Usage Guide - [WAVE Test Suite](../README.md) + +## Contents + +1. [Creating test sessions](#1-creating-test-sessions) + 1. [The landing page](#11-the-landing-page) + 2. [Configuring a new session](#12-configuring-a-new-session) + 3. [Exclude tests](#13-exclude-tests) + 1. [Manually specify tests to exclude](#131-manually-specify-tests-to-exclude) + 2. [Use a session's malfunctioning list to add tests to exclude](#132-use-a-sessions-malfunctioning-list-to-add-tests-to-exclude) + 3. [Use a previous session's exclude list to add tests to exclude](#133-use-a-previous-sessions-exclude-list-to-add-tests-to-exclude) +2. [Resuming test sessions](#2-resuming-test-sessions) + 1. [Using the webinterface](#21-using-the-webinterface) + 2. [Using a URL](#22-using-a-url) +3. [Monitoring test sessions](#3-monitoring-test-sessions) +4. [Managing test sessions](#4-managing-test-sessions) + +# 1. Creating test sessions + +Test sessions hold information about one test run one a particular device, like the current status. +Each session is identified using a UUIDv1 token string to gather these information or perform actions on it. +Each new session is configured using several parameters before the run starts. + +## 1.1 The landing page + +Every new session is created from the landing page. +It is recommended to create a new session from the device that is tested, as the user agent is part of the displayed information, as well as the browser and version, which gets parsed from it. +However, this does not influence the execution of tests or the creation of test results. +To create a new session, open the landing page on the URI path `/`. + +![landing_page] + +The landing page is divided into two section, one to create a new session and one to resume a session. +As soon as the landing is opened, a new test session is created. +Its token is displayed next to the QR-Code on the right, along with the expiration date. +As the session was created automatically, it gets removed automatically once it expires. +However, if you start the session, the expiration date gets removed and the sessions is available until you delete it. + +## 1.2 Configuring a new session + +To configure and start the session, either click on "Configure Session" or scan the QR-Code. +In most cases it is recommended to scan the QR-Code, as it does not require any interaction with the landing page on the DUT. + +![configuration_page] + +In the configuration screen you can set parameters for the new session and start it. +At the top the session's token and expiration date is displayed. Next there is the "Labels" option, which allows adding any number of labels to the session, helping to better organize sessions and allowing to apply filters while searching. +Labels can be added and modified at any point in the future. +Next there is the API selection, which allows defining the set of APIs to test in the new session. To exclude specific test or subdirectories of those selected APIs, there is the "Excluded Tests" option right below it. Here you can specify what tests to exclude in three distinct ways. (More details in [1.3 Exclude tests](#13-exclude-tests)) + +![configuration_page_bottom] + +With the "Test Types" option you specify what types of test should be included into the session: in contrast to automatic tests, manual tests require user interaction to execute properly. +The "Reference Browsers" option lets you select browsers that are used to further filter the set of tests included in the session. +Only tests that have passed the reference test session in all selected browsers are included. +The reference browsers represent the status of implementation of all WAVE APIs in modern desktop browsers, at about the time the WAVE specification was published. +To start the session press "Start Session", note that the landing page has to stay opened, as the test are going to be execute in the same window. + +[To the top](#usage-guide---wave-test-suite) + +## 1.3 Exclude tests + +To have a fine control over what test cases are executed when configuring a session, it is possible to provide a list of test cases, that are omitted in the run. + +### 1.3.1 Manually specify tests to exclude + +To add tests to exclude by providing a plain text list, click on "Add Raw" in the "Excluded Tests" setting. +This opens a input field, where you can enter multiple full paths to test files or directories. + +![Exclude List Add Raw][configuration_page_add_raw] + +Each line will be interpreted as a path to exclude a single or a group of tests. +All tests that have a path starting with one of the provided, will be excluded in the session. +Lines starting with a # symbol will be ignored, in case you want to organize test paths in a text file using comments. +Click "Add" and you will see the paths listed in the table below. + +### 1.3.2 Use a session's malfunctioning list to add tests to exclude + +When flagging tests in a running session as malfunctioning, e.g. when crashing the device, it is possible to add these test to the exclude list of the new session. +To do this, click on "Add Malfunctioning" in the "Excluded Tests" section. + +![Exclude List Add Malfunctioning][configuration_page_add_malfunctioning] + +Enter the first eight characters or more into the text field labelled "Session Token" to import all tests from the session's malfunctioning list into the new session's exclude list. +Click "Add" to confirm. +The tests should now appear in the list below. + +### 1.3.3 Use a previous session's exclude list to add tests to exclude + +If you have already specified a suitable exclude list or want to expand an existing, you can apply the exclude list of a previous session. +Click on "Add Previous Excluded" in the "Excluded Tests" section to open the corresponding controls. + +![Exclude List Add Previously Excluded][configuration_page_add_prev_excluded] + +Enter the first eight characters or more into the text field labelled "Session Token" to import all tests from the previous session's exclude list into the new session's exclude list. +Click "Add" to confirm. +The tests should now appear in the list below. + +[To the top](#usage-guide---wave-test-suite) + +# 2. Resuming test sessions + +Certain test cases may cause some devices to crash, which makes the test suite unable to automatically run the next test. +In this case, external interaction is necessary. +To alleviate the process of resuming the test session, the are two mechanisms integrated into the web interface that reduce interaction with the device to a minimum. +There is also a mechanism that can be useful if a test framework with access to the tested browser is utilized. + +## 2.1 Using the webinterface + +In any case, it is necessary to open the landing page on the device, in order to resume the session. + +![Landing Page][landing_page] + +On the landing page, in the section "Resume running session", you can see the token of the last session this device has run. +To resume this particular session, click on the "Resume" button next to it, or simply press enter or space. +If the presented token is not the one of the session you want to resume, you can change it from the configuration screen. +To get there, press the "Configure Session" button or scan the QR-Code. + +![Configuration Page][configuration_page] + +At the very bottom of the configuration page, there is a section called "Resume session", where you can see the token that was previously displayed on the landing page in a text box. +Here you can change the token of the session to resume, just enter the first eight characters or more of the token. +When you're done, press the "Resume" button. +Note that it is necessary to keep the landing page open in order to automatically run the next test, as it is loaded in the same window. + +## 2.2 Using a URL + +If you have access to the DUTs browser programmatically, you may want to resume a crashed test session automatically. +To load the next test of a specific session, simply open the following URL: + +`/next.html?token=` + +For example: + +`/next.html?token=24fcd360-ef4d-11e9-a95f-d6e1ad4c5fdb` + +[To the top](#usage-guide---wave-test-suite) + +# 3. Monitoring test sessions + +While running test sessions, the results page for second screen devices provide a convenient summary of the sessions current state, as well as controls to manipulate the test execution. +Additionally, you can flag tests in case they interrupt the test execution by, e.g. crashing the test, to exclude them in future sessions and download test results and reports. + +![results_page_top] + +On the top right-hand side, there are controls to stop, pause or delete the session. +Stopping, as well as deleting the session is irreversible. +Below you find the session's details, including the token, user agent, test paths, excluded test paths, total test file count, status, the different test timeouts, the date and time the session has been started, the date and time the session has finished, the duration and labels. + +![results_page_last_completed] + +Right below, tests that have recently completed with result status TIMEOUT are listed to add them to the list of malfunctioning tests by clicking the button with the + symbol. +Now that test appears in the list of malfunctioning tests at the very bottom of the result page. +This list can be used to exclude tests when creating a new session. (more details in [1.3.2 Use a session's malfunctioning list to add tests to exclude](#132-use-a-sessions-malfunctioning-list-to-add-tests-to-exclude)) + +![results_page_api_results] + +In the section "API Results" you can see the progress of each individual API selected for the session. +As each test file can contain multiple subtests, the count of passed, failed, timed out and not run tests does not correlate to the count of test files run, which indicates the overall progress. +Keep in mind that only test files that received a result will count as run, so even if all tests finished executing on the device, some may have failed to send the result, in which case the internal timeout has to run out to create it. + +![results_page_api_results_export] + +Once all test files of an API have received a result, it is possible to download the result data or view a report for that API, by clicking the corresponding button in the far right column of the table. + +![results_page_bottom] + +Below the table of API results, there are more options to download the results of the session. +The first option downloads the results the same way it is persisted on the serverside, along with some meta data. +This form is especially useful if you want to import the session details with the results into other instances of the WAVE Test Suite. +Furthermore, there is the option to download the raw result in JSON format of all finished APIs. +This the same JSON you get by clicking on the "JSON" button in the API results column, but of all finished APIs in a ZIP file. +Lastly, you can download a static HTML page, similiar to the results view. +Finally, at the bottom of the page you can find the list of malfunctioning tests that have been added from the list of last timed-out test files. +Remove tests by clicking their corresponding button with the trashcan icon. + +[To the top](#usage-guide---wave-test-suite) + +# 4. Managing test sessions + +The overview page provides features that help to manage and organize multiple sessions. You can access it from the URL `/overview.html`. + +![overview_page] + +In the "Manage Sessions" section you can add more sessions to the list below by entering the first eight or more characters of the token. +Clicking on "Add Session" will add the session to the list if it was the only one that could be associated with the provided token. +If there are multiple sessions that match the provided input, none will be added. +Additionally, you can compare multiple session, given that they are completed, used the same reference sessions and share tested APIs. +Simply select the desired session from the list below and click "Compare Selected". +You can also import sessions in the "Import Sessions" section, however, this feature has to be enabled in the server configuration. +Below the "Manage Sessions" section, there is the list of reference and recent sessions. + +![overview_page_sessions] + +In the sessions list, sessions are organized in three lists: Reference Browsers, which are test results everyone can see, containing the results of the reference browsers for the corresponding WAVE specification, recent sessions, which are sessions there have recently been viewed or executed on the device, and pinned sessions, which are sessions pinned by the user from the list of recent sessions. +Add label filters to show only matching sessions. + +![overview_page_sessions_pinned_recent] + +You can pin a session by clicking the button with the tag on a session in the recent sessions list and unpin them the same way from the pinned sessions list. +Click the trashcan icon to remove a session from its list, this will not delete the session results. +Sort the list of sessions by clicking on the column to filter them by. + +![overview_page_sessions_filtered] + +Add one or more tags to the filter to conveniently find the sessions you are looking for. Add labels to session when creating them or in their corresponding results page. + +[To the top](#usage-guide---wave-test-suite) + +[landing_page]: ../res/landing_page.jpg "Landing Page" +[configuration_page]: ../res/configuration_page_top.jpg "Configuration Page" +[configuration_page_bottom]: ../res/configuration_page_bottom.jpg "Configuration Page" +[configuration_page_add_raw]: ../res/configuration_page_exclude_add_raw.jpg "Exclude Tests - Add Raw" +[configuration_page_add_malfunctioning]: ../res/configuration_page_exclude_add_malfunctioning.jpg "Exclude Tests - Add Malfunctioning" +[configuration_page_add_prev_excluded]: ../res/configuration_page_exclude_add_prev_excluded.jpg "Exclude Tests - Add Previously Excluded" +[results_page_top]: ../res/results_page_top.jpg "Results Page" +[results_page_last_completed]: ../res/results_page_last_timed_out.jpg "Results Page" +[results_page_api_results]: ../res/results_page_api_results.jpg "Results Page" +[results_page_api_results_export]: ../res/results_page_api_results_export.jpg "Results Page" +[results_page_bottom]: ../res/results_page_bottom.jpg "Results Page" +[overview_page]: ../res/overview_page_top.jpg "Overview Page" +[overview_page_sessions]: ../res/overview_page_sessions.jpg "Overview Page Sessions" +[overview_page_sessions_pinned_recent]: ../res/overview_page_sessions_pinned_recent.jpg "Overview Page Sessions" +[overview_page_sessions_filtered]: ../res/overview_page_sessions_filtered.jpg "Overview Page Filter" diff --git a/tests/wpt/web-platform-tests/tools/wave/export/css/bulma.min.css b/tests/wpt/web-platform-tests/tools/wave/export/css/bulma.min.css new file mode 100644 index 00000000000..70f6e4450e8 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/export/css/bulma.min.css @@ -0,0 +1 @@ +/*! bulma.io v0.7.4 | MIT License | github.com/jgthms/bulma */@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.breadcrumb,.button,.delete,.file,.is-unselectable,.modal-close,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:center;transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.highlight:not(:last-child),.level:not(:last-child),.list:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.25em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.375em - 1px);padding-left:calc(.625em - 1px);padding-right:calc(.625em - 1px);padding-top:calc(.375em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}embed,iframe,img,object,video{height:auto;max-width:100%}audio{max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0;text-align:left}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1rem;font-weight:400;line-height:1.5}a{color:#3273dc;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#ff3860;font-size:.875em;font-weight:400;padding:.25em .5em .25em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type=checkbox],input[type=radio]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{text-align:left;vertical-align:top}table th{color:#363636}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left!important}.is-pulled-right{float:right!important}.is-clipped{overflow:hidden!important}.is-size-1{font-size:3rem!important}.is-size-2{font-size:2.5rem!important}.is-size-3{font-size:2rem!important}.is-size-4{font-size:1.5rem!important}.is-size-5{font-size:1.25rem!important}.is-size-6{font-size:1rem!important}.is-size-7{font-size:.75rem!important}@media screen and (max-width:768px){.is-size-1-mobile{font-size:3rem!important}.is-size-2-mobile{font-size:2.5rem!important}.is-size-3-mobile{font-size:2rem!important}.is-size-4-mobile{font-size:1.5rem!important}.is-size-5-mobile{font-size:1.25rem!important}.is-size-6-mobile{font-size:1rem!important}.is-size-7-mobile{font-size:.75rem!important}}@media screen and (min-width:769px),print{.is-size-1-tablet{font-size:3rem!important}.is-size-2-tablet{font-size:2.5rem!important}.is-size-3-tablet{font-size:2rem!important}.is-size-4-tablet{font-size:1.5rem!important}.is-size-5-tablet{font-size:1.25rem!important}.is-size-6-tablet{font-size:1rem!important}.is-size-7-tablet{font-size:.75rem!important}}@media screen and (max-width:1087px){.is-size-1-touch{font-size:3rem!important}.is-size-2-touch{font-size:2.5rem!important}.is-size-3-touch{font-size:2rem!important}.is-size-4-touch{font-size:1.5rem!important}.is-size-5-touch{font-size:1.25rem!important}.is-size-6-touch{font-size:1rem!important}.is-size-7-touch{font-size:.75rem!important}}@media screen and (min-width:1088px){.is-size-1-desktop{font-size:3rem!important}.is-size-2-desktop{font-size:2.5rem!important}.is-size-3-desktop{font-size:2rem!important}.is-size-4-desktop{font-size:1.5rem!important}.is-size-5-desktop{font-size:1.25rem!important}.is-size-6-desktop{font-size:1rem!important}.is-size-7-desktop{font-size:.75rem!important}}@media screen and (min-width:1280px){.is-size-1-widescreen{font-size:3rem!important}.is-size-2-widescreen{font-size:2.5rem!important}.is-size-3-widescreen{font-size:2rem!important}.is-size-4-widescreen{font-size:1.5rem!important}.is-size-5-widescreen{font-size:1.25rem!important}.is-size-6-widescreen{font-size:1rem!important}.is-size-7-widescreen{font-size:.75rem!important}}@media screen and (min-width:1472px){.is-size-1-fullhd{font-size:3rem!important}.is-size-2-fullhd{font-size:2.5rem!important}.is-size-3-fullhd{font-size:2rem!important}.is-size-4-fullhd{font-size:1.5rem!important}.is-size-5-fullhd{font-size:1.25rem!important}.is-size-6-fullhd{font-size:1rem!important}.is-size-7-fullhd{font-size:.75rem!important}}.has-text-centered{text-align:center!important}.has-text-justified{text-align:justify!important}.has-text-left{text-align:left!important}.has-text-right{text-align:right!important}@media screen and (max-width:768px){.has-text-centered-mobile{text-align:center!important}}@media screen and (min-width:769px),print{.has-text-centered-tablet{text-align:center!important}}@media screen and (min-width:769px) and (max-width:1087px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1087px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1088px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1088px) and (max-width:1279px){.has-text-centered-desktop-only{text-align:center!important}}@media screen and (min-width:1280px){.has-text-centered-widescreen{text-align:center!important}}@media screen and (min-width:1280px) and (max-width:1471px){.has-text-centered-widescreen-only{text-align:center!important}}@media screen and (min-width:1472px){.has-text-centered-fullhd{text-align:center!important}}@media screen and (max-width:768px){.has-text-justified-mobile{text-align:justify!important}}@media screen and (min-width:769px),print{.has-text-justified-tablet{text-align:justify!important}}@media screen and (min-width:769px) and (max-width:1087px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1087px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1088px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1088px) and (max-width:1279px){.has-text-justified-desktop-only{text-align:justify!important}}@media screen and (min-width:1280px){.has-text-justified-widescreen{text-align:justify!important}}@media screen and (min-width:1280px) and (max-width:1471px){.has-text-justified-widescreen-only{text-align:justify!important}}@media screen and (min-width:1472px){.has-text-justified-fullhd{text-align:justify!important}}@media screen and (max-width:768px){.has-text-left-mobile{text-align:left!important}}@media screen and (min-width:769px),print{.has-text-left-tablet{text-align:left!important}}@media screen and (min-width:769px) and (max-width:1087px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1087px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1088px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1088px) and (max-width:1279px){.has-text-left-desktop-only{text-align:left!important}}@media screen and (min-width:1280px){.has-text-left-widescreen{text-align:left!important}}@media screen and (min-width:1280px) and (max-width:1471px){.has-text-left-widescreen-only{text-align:left!important}}@media screen and (min-width:1472px){.has-text-left-fullhd{text-align:left!important}}@media screen and (max-width:768px){.has-text-right-mobile{text-align:right!important}}@media screen and (min-width:769px),print{.has-text-right-tablet{text-align:right!important}}@media screen and (min-width:769px) and (max-width:1087px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1087px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1088px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1088px) and (max-width:1279px){.has-text-right-desktop-only{text-align:right!important}}@media screen and (min-width:1280px){.has-text-right-widescreen{text-align:right!important}}@media screen and (min-width:1280px) and (max-width:1471px){.has-text-right-widescreen-only{text-align:right!important}}@media screen and (min-width:1472px){.has-text-right-fullhd{text-align:right!important}}.is-capitalized{text-transform:capitalize!important}.is-lowercase{text-transform:lowercase!important}.is-uppercase{text-transform:uppercase!important}.is-italic{font-style:italic!important}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-link{color:#3273dc!important}a.has-text-link:focus,a.has-text-link:hover{color:#205bbc!important}.has-background-link{background-color:#3273dc!important}.has-text-info{color:#209cee!important}a.has-text-info:focus,a.has-text-info:hover{color:#0f81cc!important}.has-background-info{background-color:#209cee!important}.has-text-success{color:#23d160!important}a.has-text-success:focus,a.has-text-success:hover{color:#1ca64c!important}.has-background-success{background-color:#23d160!important}.has-text-warning{color:#ffdd57!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd324!important}.has-background-warning{background-color:#ffdd57!important}.has-text-danger{color:#ff3860!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ff0537!important}.has-background-danger{background-color:#ff3860!important}.has-text-black-bis{color:#121212!important}.has-background-black-bis{background-color:#121212!important}.has-text-black-ter{color:#242424!important}.has-background-black-ter{background-color:#242424!important}.has-text-grey-darker{color:#363636!important}.has-background-grey-darker{background-color:#363636!important}.has-text-grey-dark{color:#4a4a4a!important}.has-background-grey-dark{background-color:#4a4a4a!important}.has-text-grey{color:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!important}.has-text-grey-light{color:#b5b5b5!important}.has-background-grey-light{background-color:#b5b5b5!important}.has-text-grey-lighter{color:#dbdbdb!important}.has-background-grey-lighter{background-color:#dbdbdb!important}.has-text-white-ter{color:#f5f5f5!important}.has-background-white-ter{background-color:#f5f5f5!important}.has-text-white-bis{color:#fafafa!important}.has-background-white-bis{background-color:#fafafa!important}.has-text-weight-light{font-weight:300!important}.has-text-weight-normal{font-weight:400!important}.has-text-weight-semibold{font-weight:600!important}.has-text-weight-bold{font-weight:700!important}.is-family-primary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family:monospace!important}.is-block{display:block!important}@media screen and (max-width:768px){.is-block-mobile{display:block!important}}@media screen and (min-width:769px),print{.is-block-tablet{display:block!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1087px){.is-block-touch{display:block!important}}@media screen and (min-width:1088px){.is-block-desktop{display:block!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-block-desktop-only{display:block!important}}@media screen and (min-width:1280px){.is-block-widescreen{display:block!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-block-widescreen-only{display:block!important}}@media screen and (min-width:1472px){.is-block-fullhd{display:block!important}}.is-flex{display:flex!important}@media screen and (max-width:768px){.is-flex-mobile{display:flex!important}}@media screen and (min-width:769px),print{.is-flex-tablet{display:flex!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1087px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1088px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-flex-desktop-only{display:flex!important}}@media screen and (min-width:1280px){.is-flex-widescreen{display:flex!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-flex-widescreen-only{display:flex!important}}@media screen and (min-width:1472px){.is-flex-fullhd{display:flex!important}}.is-inline{display:inline!important}@media screen and (max-width:768px){.is-inline-mobile{display:inline!important}}@media screen and (min-width:769px),print{.is-inline-tablet{display:inline!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1087px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1088px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-inline-desktop-only{display:inline!important}}@media screen and (min-width:1280px){.is-inline-widescreen{display:inline!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-inline-widescreen-only{display:inline!important}}@media screen and (min-width:1472px){.is-inline-fullhd{display:inline!important}}.is-inline-block{display:inline-block!important}@media screen and (max-width:768px){.is-inline-block-mobile{display:inline-block!important}}@media screen and (min-width:769px),print{.is-inline-block-tablet{display:inline-block!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1087px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1088px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-inline-block-desktop-only{display:inline-block!important}}@media screen and (min-width:1280px){.is-inline-block-widescreen{display:inline-block!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-inline-block-widescreen-only{display:inline-block!important}}@media screen and (min-width:1472px){.is-inline-block-fullhd{display:inline-block!important}}.is-inline-flex{display:inline-flex!important}@media screen and (max-width:768px){.is-inline-flex-mobile{display:inline-flex!important}}@media screen and (min-width:769px),print{.is-inline-flex-tablet{display:inline-flex!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1087px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1088px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-inline-flex-desktop-only{display:inline-flex!important}}@media screen and (min-width:1280px){.is-inline-flex-widescreen{display:inline-flex!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-inline-flex-widescreen-only{display:inline-flex!important}}@media screen and (min-width:1472px){.is-inline-flex-fullhd{display:inline-flex!important}}.is-hidden{display:none!important}.is-sr-only{border:none!important;clip:rect(0,0,0,0)!important;height:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.01em!important}@media screen and (max-width:768px){.is-hidden-mobile{display:none!important}}@media screen and (min-width:769px),print{.is-hidden-tablet{display:none!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1087px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1088px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-hidden-desktop-only{display:none!important}}@media screen and (min-width:1280px){.is-hidden-widescreen{display:none!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-hidden-widescreen-only{display:none!important}}@media screen and (min-width:1472px){.is-hidden-fullhd{display:none!important}}.is-invisible{visibility:hidden!important}@media screen and (max-width:768px){.is-invisible-mobile{visibility:hidden!important}}@media screen and (min-width:769px),print{.is-invisible-tablet{visibility:hidden!important}}@media screen and (min-width:769px) and (max-width:1087px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1087px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1088px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1088px) and (max-width:1279px){.is-invisible-desktop-only{visibility:hidden!important}}@media screen and (min-width:1280px){.is-invisible-widescreen{visibility:hidden!important}}@media screen and (min-width:1280px) and (max-width:1471px){.is-invisible-widescreen-only{visibility:hidden!important}}@media screen and (min-width:1472px){.is-invisible-fullhd{visibility:hidden!important}}.is-marginless{margin:0!important}.is-paddingless{padding:0!important}.is-radiusless{border-radius:0!important}.is-shadowless{box-shadow:none!important}.box{background-color:#fff;border-radius:6px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px #3273dc}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #3273dc}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.375em - 1px);padding-left:.75em;padding-right:.75em;padding-top:calc(.375em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.375em - 1px);margin-right:.1875em}.button .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:calc(-.375em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.375em - 1px);margin-right:calc(-.375em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#3273dc;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:#363636}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:#363636}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:#363636}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:#363636}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.button.is-light.is-inverted{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted:hover{background-color:#292929}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:#363636;border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark{background-color:#363636;border-color:transparent;color:#f5f5f5}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#f5f5f5}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:transparent;box-shadow:none}.button.is-dark.is-inverted{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted:hover{background-color:#e8e8e8}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#f5f5f5;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:transparent;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link{background-color:#3273dc;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#276cda;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#2366d1;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#3273dc;border-color:transparent;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#3273dc}.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3273dc}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;color:#3273dc}.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#3273dc;border-color:#3273dc;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;box-shadow:none;color:#3273dc}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#1496ed;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#118fe4;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:transparent;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success{background-color:#23d160;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#22c65b;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#20bc56;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#23d160;border-color:transparent;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#23d160}.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#23d160}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#23d160;color:#23d160}.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#23d160;border-color:#23d160;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #23d160 #23d160!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#23d160;box-shadow:none;color:#23d160}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#23d160}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-danger{background-color:#ff3860;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#ff2b56;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ff1f4b;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#ff3860;border-color:transparent;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ff3860}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;color:#ff3860}.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#ff3860;border-color:#ff3860;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #ff3860 #ff3860!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;box-shadow:none;color:#ff3860}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-small{border-radius:2px;font-size:.75rem}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em / 2));top:calc(50% - (1em / 2));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:290486px;padding-left:1em;padding-right:1em}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1}.buttons.is-centered{justify-content:center}.buttons.is-right{justify-content:flex-end}.container{margin:0 auto;position:relative}@media screen and (min-width:1088px){.container{max-width:960px;width:960px}.container.is-fluid{margin-left:64px;margin-right:64px;max-width:none;width:auto}}@media screen and (max-width:1279px){.container.is-widescreen{max-width:1152px;width:auto}}@media screen and (max-width:1471px){.container.is-fullhd{max-width:1344px;width:auto}}@media screen and (min-width:1280px){.container{max-width:1152px;width:1152px}}@media screen and (min-width:1472px){.container{max-width:1344px;width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636;text-align:left}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content.is-small{font-size:.75rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.input,.textarea{background-color:#fff;border-color:#dbdbdb;color:#363636;box-shadow:inset 0 1px 2px rgba(10,10,10,.1);max-width:100%;width:100%}.input::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input.is-hovered,.input:hover,.textarea.is-hovered,.textarea:hover{border-color:#b5b5b5}.input.is-active,.input.is-focused,.input:active,.input:focus,.textarea.is-active,.textarea.is-focused,.textarea:active,.textarea:focus{border-color:#3273dc;box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.input[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input[readonly],.textarea[readonly]{box-shadow:none}.input.is-white,.textarea.is-white{border-color:#fff}.input.is-white.is-active,.input.is-white.is-focused,.input.is-white:active,.input.is-white:focus,.textarea.is-white.is-active,.textarea.is-white.is-focused,.textarea.is-white:active,.textarea.is-white:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.input.is-black,.textarea.is-black{border-color:#0a0a0a}.input.is-black.is-active,.input.is-black.is-focused,.input.is-black:active,.input.is-black:focus,.textarea.is-black.is-active,.textarea.is-black.is-focused,.textarea.is-black:active,.textarea.is-black:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.input.is-light,.textarea.is-light{border-color:#f5f5f5}.input.is-light.is-active,.input.is-light.is-focused,.input.is-light:active,.input.is-light:focus,.textarea.is-light.is-active,.textarea.is-light.is-focused,.textarea.is-light:active,.textarea.is-light:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.input.is-dark,.textarea.is-dark{border-color:#363636}.input.is-dark.is-active,.input.is-dark.is-focused,.input.is-dark:active,.input.is-dark:focus,.textarea.is-dark.is-active,.textarea.is-dark.is-focused,.textarea.is-dark:active,.textarea.is-dark:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.input.is-primary,.textarea.is-primary{border-color:#00d1b2}.input.is-primary.is-active,.input.is-primary.is-focused,.input.is-primary:active,.input.is-primary:focus,.textarea.is-primary.is-active,.textarea.is-primary.is-focused,.textarea.is-primary:active,.textarea.is-primary:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.input.is-link,.textarea.is-link{border-color:#3273dc}.input.is-link.is-active,.input.is-link.is-focused,.input.is-link:active,.input.is-link:focus,.textarea.is-link.is-active,.textarea.is-link.is-focused,.textarea.is-link:active,.textarea.is-link:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.input.is-info,.textarea.is-info{border-color:#209cee}.input.is-info.is-active,.input.is-info.is-focused,.input.is-info:active,.input.is-info:focus,.textarea.is-info.is-active,.textarea.is-info.is-focused,.textarea.is-info:active,.textarea.is-info:focus{box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.input.is-success,.textarea.is-success{border-color:#23d160}.input.is-success.is-active,.input.is-success.is-focused,.input.is-success:active,.input.is-success:focus,.textarea.is-success.is-active,.textarea.is-success.is-focused,.textarea.is-success:active,.textarea.is-success:focus{box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.input.is-warning,.textarea.is-warning{border-color:#ffdd57}.input.is-warning.is-active,.input.is-warning.is-focused,.input.is-warning:active,.input.is-warning:focus,.textarea.is-warning.is-active,.textarea.is-warning.is-focused,.textarea.is-warning:active,.textarea.is-warning:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.input.is-danger,.textarea.is-danger{border-color:#ff3860}.input.is-danger.is-active,.input.is-danger.is-focused,.input.is-danger:active,.input.is-danger:focus,.textarea.is-danger.is-active,.textarea.is-danger.is-focused,.textarea.is-danger:active,.textarea.is-danger:focus{box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.input.is-small,.textarea.is-small{border-radius:2px;font-size:.75rem}.input.is-medium,.textarea.is-medium{font-size:1.25rem}.input.is-large,.textarea.is-large{font-size:1.5rem}.input.is-fullwidth,.textarea.is-fullwidth{display:block;width:100%}.input.is-inline,.textarea.is-inline{display:inline;width:auto}.input.is-rounded{border-radius:290486px;padding-left:1em;padding-right:1em}.input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:.625em;resize:vertical}.textarea:not([rows]){max-height:600px;min-height:120px}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.25em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#3273dc;right:1.125em;z-index:4}.select.is-rounded select{border-radius:290486px;padding-left:1em}.select select{background-color:#fff;border-color:#dbdbdb;color:#363636;cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.select select::-moz-placeholder{color:rgba(54,54,54,.3)}.select select::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.select select:-moz-placeholder{color:rgba(54,54,54,.3)}.select select:-ms-input-placeholder{color:rgba(54,54,54,.3)}.select select.is-hovered,.select select:hover{border-color:#b5b5b5}.select select.is-active,.select select.is-focused,.select select:active,.select select:focus{border-color:#3273dc;box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.select select[disabled],fieldset[disabled] .select select{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.select select[disabled]::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder{color:rgba(122,122,122,.3)}.select select[disabled]::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.select select[disabled]:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder{color:rgba(122,122,122,.3)}.select select[disabled]:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder{color:rgba(122,122,122,.3)}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#3273dc}.select.is-link select{border-color:#3273dc}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#2366d1}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.select.is-info:not(:hover)::after{border-color:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#118fe4}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.select.is-success:not(:hover)::after{border-color:#23d160}.select.is-success select{border-color:#23d160}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#20bc56}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd83d}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.select.is-danger:not(:hover)::after{border-color:#ff3860}.select.is-danger select{border-color:#ff3860}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ff1f4b}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.select.is-small{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#7a7a7a}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;-webkit-transform:none;transform:none}.select.is-loading.is-small:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:#363636}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:#363636}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:#363636}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:#363636}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#f5f5f5}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#f5f5f5}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#f5f5f5}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#3273dc;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#276cda;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,115,220,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#2366d1;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#209cee;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#1496ed;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(32,156,238,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#118fe4;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#23d160;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#22c65b;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(35,209,96,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#20bc56;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,221,87,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#ff3860;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#ff2b56;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,56,96,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ff1f4b;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:left;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#3273dc}.help.is-info{color:#209cee}.help.is-success{color:#23d160}.help.is-warning{color:#ffdd57}.help.is-danger{color:#ff3860}.field:not(:last-child){margin-bottom:.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus:hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width:769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width:768px){.field-label{margin-bottom:.5rem}}@media screen and (min-width:769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width:769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:left}.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#7a7a7a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.25em;pointer-events:none;position:absolute;top:0;width:2.25em;z-index:4}.control.has-icons-left .input,.control.has-icons-left .select select{padding-left:2.25em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right .select select{padding-right:2.25em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute!important;right:.625em;top:.625em;z-index:4}.control.is-loading.is-small:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:290486px}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;padding:1.25rem 2.5rem 1.25rem 1.5rem;position:relative}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:0 0}.notification>.delete{position:absolute;right:.5rem;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:#363636}.notification.is-dark{background-color:#363636;color:#f5f5f5}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-link{background-color:#3273dc;color:#fff}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-success{background-color:#23d160;color:#fff}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.notification.is-danger{background-color:#ff3860;color:#fff}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#dbdbdb}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;border:none}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#dbdbdb;background-image:linear-gradient(to right,#4a4a4a 30%,#dbdbdb 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right,#fff 30%,#dbdbdb 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right,#0a0a0a 30%,#dbdbdb 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right,#f5f5f5 30%,#dbdbdb 30%)}.progress.is-dark::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#dbdbdb 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#dbdbdb 30%)}.progress.is-link::-webkit-progress-value{background-color:#3273dc}.progress.is-link::-moz-progress-bar{background-color:#3273dc}.progress.is-link::-ms-fill{background-color:#3273dc}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#3273dc 30%,#dbdbdb 30%)}.progress.is-info::-webkit-progress-value{background-color:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#209cee 30%,#dbdbdb 30%)}.progress.is-success::-webkit-progress-value{background-color:#23d160}.progress.is-success::-moz-progress-bar{background-color:#23d160}.progress.is-success::-ms-fill{background-color:#23d160}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#23d160 30%,#dbdbdb 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right,#ffdd57 30%,#dbdbdb 30%)}.progress.is-danger::-webkit-progress-value{background-color:#ff3860}.progress.is-danger::-moz-progress-bar{background-color:#ff3860}.progress.is-danger::-ms-fill{background-color:#ff3860}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#ff3860 30%,#dbdbdb 30%)}.progress.is-small{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#f5f5f5}.table td.is-primary,.table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#3273dc;border-color:#3273dc;color:#fff}.table td.is-info,.table th.is-info{background-color:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#23d160;border-color:#23d160;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#ff3860;border-color:#ff3860;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#00d1b2;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table th{color:#363636;text-align:left}.table tr.is-selected{background-color:#00d1b2;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:.25em .5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.tags.has-addons .tag:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.tags.has-addons .tag:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:#363636}.tag:not(body).is-dark{background-color:#363636;color:#f5f5f5}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-link{background-color:#3273dc;color:#fff}.tag:not(body).is-info{background-color:#209cee;color:#fff}.tag:not(body).is-success{background-color:#23d160;color:#fff}.tag:not(body).is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.tag:not(body).is-danger{background-color:#ff3860;color:#fff}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:290486px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title+.highlight{margin-top:-.75rem}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{align-items:center;background-color:#f5f5f5;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#3273dc;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);color:#4a4a4a;max-width:100%;position:relative}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 1px 2px rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem}.card-image{display:block;position:relative}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;border-top:1px solid #dbdbdb;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #dbdbdb}.card .media:not(:last-child){margin-bottom:.75rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:left;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#3273dc;color:#fff}.dropdown-divider{background-color:#dbdbdb;border:none;display:block;height:1px;margin:.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width:769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .subtitle,.level-item .title{margin-bottom:0}@media screen and (max-width:768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width:769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width:768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width:769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width:769px),print{.level-right{display:flex}}.list{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1)}.list-item{display:block;padding:.5em 1em}.list-item:not(a){color:#4a4a4a}.list-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-item:last-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-item:not(:last-child){border-bottom:1px solid #dbdbdb}.list-item.is-active{background-color:#3273dc;color:#fff}a.list-item{background-color:#f5f5f5;cursor:pointer}.media{align-items:flex-start;display:flex;text-align:left}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:left}@media screen and (max-width:768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#3273dc;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff;color:#4d4d4d}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a;color:#090909}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:#363636}.message.is-light .message-body{border-color:#f5f5f5;color:#505050}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#f5f5f5}.message.is-dark .message-body{border-color:#363636;color:#2a2a2a}.message.is-primary{background-color:#f5fffd}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#021310}.message.is-link{background-color:#f6f9fe}.message.is-link .message-header{background-color:#3273dc;color:#fff}.message.is-link .message-body{border-color:#3273dc;color:#22509a}.message.is-info{background-color:#f6fbfe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#12537e}.message.is-success{background-color:#f6fef9}.message.is-success .message-header{background-color:#23d160;color:#fff}.message.is-success .message-body{border-color:#23d160;color:#0e301a}.message.is-warning{background-color:#fffdf5}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#3b3108}.message.is-danger{background-color:#fff5f7}.message.is-danger .message-header{background-color:#ff3860;color:#fff}.message.is-danger .message-body{border-color:#ff3860;color:#cd0930}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px),print{.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-foot,.modal-card-head{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#363636;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:10px}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width:1088px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand .navbar-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:#363636}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:#363636}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-brand .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-burger{color:#363636}@media screen and (min-width:1088px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:#363636}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#363636}}.navbar.is-dark{background-color:#363636;color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-burger{color:#f5f5f5}@media screen and (min-width:1088px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#f5f5f5}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#f5f5f5}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#3273dc;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#3273dc;color:#fff}}.navbar.is-info{background-color:#209cee;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#23d160;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#23d160;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1088px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#ff3860;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width:1088px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#ff3860;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;-webkit-transform-origin:center;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,-webkit-transform;transition-property:background-color,opacity,transform;transition-property:background-color,opacity,transform,-webkit-transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:nth-child(1){-webkit-transform:translateY(5px) rotate(45deg);transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){-webkit-transform:translateY(-5px) rotate(-45deg);transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:hover{background-color:#fafafa;color:#3273dc}.navbar-item{display:block;flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#3273dc}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#3273dc;border-bottom-style:solid;border-bottom-width:3px;color:#3273dc;padding-bottom:calc(.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#3273dc;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:.5rem 0}@media screen and (max-width:1087px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1088px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:hover{background-color:transparent!important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent!important}.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item{display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{-webkit-transform:rotate(135deg) translate(.25em,-.25em);transform:rotate(135deg) translate(.25em,-.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{opacity:1;pointer-events:auto;-webkit-transform:translateY(0);transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));-webkit-transform:translateY(-5px);transform:translateY(-5px);transition-duration:86ms;transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:hover),a.navbar-item.is-active:not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:hover .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:290486px}.pagination.is-rounded .pagination-link{border-radius:290486px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;padding-left:.5em;padding-right:.5em;justify-content:center;margin:.25rem;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.25em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#3273dc}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#3273dc;border-color:#3273dc;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width:769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel-block,.panel-heading,.panel-tabs{border-bottom:1px solid #dbdbdb;border-left:1px solid #dbdbdb;border-right:1px solid #dbdbdb}.panel-block:first-child,.panel-heading:first-child,.panel-tabs:first-child{border-top:1px solid #dbdbdb}.panel-heading{background-color:#f5f5f5;border-radius:4px 4px 0 0;color:#363636;font-size:1.25em;font-weight:300;line-height:1.25;padding:.5em .75em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#3273dc}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .75em}.panel-block input[type=checkbox]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#3273dc;color:#363636}.panel-block.is-active .panel-icon{color:#3273dc}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#7a7a7a;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#3273dc;color:#3273dc}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:transparent!important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-radius:4px 0 0 4px}.tabs.is-toggle li:last-child a{border-radius:0 4px 4px 0}.tabs.is-toggle li.is-active a{background-color:#3273dc;border-color:#3273dc;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:290486px;border-top-left-radius:290486px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}.tabs.is-small{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-1{flex:none;width:8.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width:768px){.column.is-narrow-mobile{flex:none}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-1-mobile{flex:none;width:8.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width:769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width:1087px){.column.is-narrow-touch{flex:none}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-1-touch{flex:none;width:8.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1088px){.column.is-narrow-desktop{flex:none}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-1-desktop{flex:none;width:8.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width:1280px){.column.is-narrow-widescreen{flex:none}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-1-widescreen{flex:none;width:8.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width:1472px){.column.is-narrow-fullhd{flex:none}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-1-fullhd{flex:none;width:8.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0!important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width:1088px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap:0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable .column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap:0rem}@media screen and (max-width:768px){.columns.is-variable.is-0-mobile{--columnGap:0rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-0-tablet{--columnGap:0rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1087px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1088px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-0-desktop-only{--columnGap:0rem}}@media screen and (min-width:1280px){.columns.is-variable.is-0-widescreen{--columnGap:0rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-0-widescreen-only{--columnGap:0rem}}@media screen and (min-width:1472px){.columns.is-variable.is-0-fullhd{--columnGap:0rem}}.columns.is-variable.is-1{--columnGap:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1087px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1088px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1280px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1472px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1087px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1088px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1280px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1472px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1087px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1088px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1280px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1472px){.columns.is-variable.is-3-fullhd{--columnGap:0.75rem}}.columns.is-variable.is-4{--columnGap:1rem}@media screen and (max-width:768px){.columns.is-variable.is-4-mobile{--columnGap:1rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-4-tablet{--columnGap:1rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1087px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1088px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-4-desktop-only{--columnGap:1rem}}@media screen and (min-width:1280px){.columns.is-variable.is-4-widescreen{--columnGap:1rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-4-widescreen-only{--columnGap:1rem}}@media screen and (min-width:1472px){.columns.is-variable.is-4-fullhd{--columnGap:1rem}}.columns.is-variable.is-5{--columnGap:1.25rem}@media screen and (max-width:768px){.columns.is-variable.is-5-mobile{--columnGap:1.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-5-tablet{--columnGap:1.25rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1087px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1088px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-5-desktop-only{--columnGap:1.25rem}}@media screen and (min-width:1280px){.columns.is-variable.is-5-widescreen{--columnGap:1.25rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-5-widescreen-only{--columnGap:1.25rem}}@media screen and (min-width:1472px){.columns.is-variable.is-5-fullhd{--columnGap:1.25rem}}.columns.is-variable.is-6{--columnGap:1.5rem}@media screen and (max-width:768px){.columns.is-variable.is-6-mobile{--columnGap:1.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-6-tablet{--columnGap:1.5rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1087px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1088px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-6-desktop-only{--columnGap:1.5rem}}@media screen and (min-width:1280px){.columns.is-variable.is-6-widescreen{--columnGap:1.5rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-6-widescreen-only{--columnGap:1.5rem}}@media screen and (min-width:1472px){.columns.is-variable.is-6-fullhd{--columnGap:1.5rem}}.columns.is-variable.is-7{--columnGap:1.75rem}@media screen and (max-width:768px){.columns.is-variable.is-7-mobile{--columnGap:1.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-7-tablet{--columnGap:1.75rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1087px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1088px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-7-desktop-only{--columnGap:1.75rem}}@media screen and (min-width:1280px){.columns.is-variable.is-7-widescreen{--columnGap:1.75rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-7-widescreen-only{--columnGap:1.75rem}}@media screen and (min-width:1472px){.columns.is-variable.is-7-fullhd{--columnGap:1.75rem}}.columns.is-variable.is-8{--columnGap:2rem}@media screen and (max-width:768px){.columns.is-variable.is-8-mobile{--columnGap:2rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-8-tablet{--columnGap:2rem}}@media screen and (min-width:769px) and (max-width:1087px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1087px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1088px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1088px) and (max-width:1279px){.columns.is-variable.is-8-desktop-only{--columnGap:2rem}}@media screen and (min-width:1280px){.columns.is-variable.is-8-widescreen{--columnGap:2rem}}@media screen and (min-width:1280px) and (max-width:1471px){.columns.is-variable.is-8-widescreen-only{--columnGap:2rem}}@media screen and (min-width:1472px){.columns.is-variable.is-8-fullhd{--columnGap:2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0!important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem!important}@media screen and (min-width:769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1087px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}@media screen and (max-width:768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:#363636}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag),.hero.is-light strong{color:inherit}.hero.is-light .title{color:#363636}.hero.is-light .subtitle{color:rgba(54,54,54,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:#363636}@media screen and (max-width:1087px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(54,54,54,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.hero.is-light .tabs a{color:#363636;opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:#363636}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}}.hero.is-dark{background-color:#363636;color:#f5f5f5}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#f5f5f5}.hero.is-dark .subtitle{color:rgba(245,245,245,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#f5f5f5}@media screen and (max-width:1087px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(245,245,245,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.hero.is-dark .tabs a{color:#f5f5f5;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#f5f5f5}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.hero.is-dark.is-bold{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}@media screen and (max-width:768px){.hero.is-dark.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#3273dc;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-link .navbar-menu{background-color:#3273dc}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#2366d1;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3273dc}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}}.hero.is-info{background-color:#209cee;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-info .navbar-menu{background-color:#209cee}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#118fe4;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#04a6d7 0,#209cee 71%,#3287f5 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#04a6d7 0,#209cee 71%,#3287f5 100%)}}.hero.is-success{background-color:#23d160;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-success .navbar-menu{background-color:#23d160}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#20bc56;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#23d160}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#12af2f 0,#23d160 71%,#2ce28a 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#12af2f 0,#23d160 71%,#2ce28a 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1087px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}}.hero.is-danger{background-color:#ff3860;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1087px){.hero.is-danger .navbar-menu{background-color:#ff3860}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ff3860}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#ff0561 0,#ff3860 71%,#ff5257 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ff0561 0,#ff3860 71%,#ff5257 100%)}}.hero.is-small .hero-body{padding-bottom:1.5rem;padding-top:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding-bottom:9rem;padding-top:9rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding-bottom:18rem;padding-top:18rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.hero-video.is-transparent{opacity:.3}@media screen and (max-width:768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width:768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:.75rem}}@media screen and (min-width:769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}.section{padding:3rem 1.5rem}@media screen and (min-width:1088px){.section.is-medium{padding:9rem 1.5rem}.section.is-large{padding:18rem 1.5rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/export/css/result.css b/tests/wpt/web-platform-tests/tools/wave/export/css/result.css new file mode 100644 index 00000000000..9e7c4dc0ba4 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/export/css/result.css @@ -0,0 +1,75 @@ +body { + margin: 0; + padding: 0; + display: flex; + justify-content: center; + font-family: "Noto Sans" sans-serif; + background-color: white; + color: #000; +} + +.header { + display: flex; + margin: 50px 0 30px 0; +} + +.header :first-child { + flex: 1; +} + +.site-logo { + max-width: 300px; + margin-left: -15px; +} + +.content { + width: 1000px; +} + +#test-path, +#token { + font-family: monospace; + font-size: 12pt; +} + +.pass { + color: green; +} + +.fail { + color: red; +} + +.timeout { + color: rgb(224, 127, 0); +} + +.not-run { + color: blue; +} + +.api-result-timeoutfiles { + display: none; /* don't display for now */ + flex-basis: 100%; +} + +#header { + display: flex; + align-items: center; +} + +#header > :first-child { + flex: 1; +} + +#controls-wrapper { + display: flex; +} + +.no-border-radius { + border-radius: 0; +} + +#results-table .button { + margin: 0 2px; +} diff --git a/tests/wpt/web-platform-tests/tools/wave/export/index.html b/tests/wpt/web-platform-tests/tools/wave/export/index.html new file mode 100644 index 00000000000..73de099eef9 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/export/index.html @@ -0,0 +1,375 @@ + + + + + Results - Web Platform Test + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/export/lib/ui.js b/tests/wpt/web-platform-tests/tools/wave/export/lib/ui.js new file mode 100644 index 00000000000..59e2b786e50 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/export/lib/ui.js @@ -0,0 +1,64 @@ +const UI = { + createElement: config => { + if (!config) return document.createElement("div"); + const elementType = config.element || "div"; + const element = document.createElement(elementType); + + Object.keys(config).forEach(property => { + const value = config[property]; + switch (property.toLowerCase()) { + case "id": + case "src": + case "style": + case "placeholder": + case "title": + element.setAttribute(property, value); + return; + case "classname": + element.setAttribute("class", value); + return; + case "text": + element.innerText = value; + return; + case "html": + element.innerHTML = value; + return; + case "onclick": + element.onclick = value.bind(element); + return; + case "onchange": + element.onchange = value.bind(element); + return; + case "onkeydown": + element.onkeydown = value.bind(element); + return; + case "type": + if (elementType === "input") element.setAttribute("type", value); + return; + case "children": + if (value instanceof Array) { + value.forEach(child => + element.appendChild( + child instanceof Element ? child : UI.createElement(child) + ) + ); + } else { + element.appendChild( + value instanceof Element ? value : UI.createElement(value) + ); + } + return; + case "disabled": + if (value) element.setAttribute("disabled", true); + return; + } + }); + return element; + }, + getElement: id => { + return document.getElementById(id); + }, + getRoot: () => { + return document.getElementsByTagName("body")[0]; + } +}; diff --git a/tests/wpt/web-platform-tests/tools/wave/export/lib/utils.js b/tests/wpt/web-platform-tests/tools/wave/export/lib/utils.js new file mode 100644 index 00000000000..cbd75b52165 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/export/lib/utils.js @@ -0,0 +1,40 @@ +const utils = { + parseQuery: queryString => { + if (queryString.indexOf("?") === -1) return {}; + queryString = queryString.split("?")[1]; + const query = {}; + for (let part of queryString.split("&")) { + const keyValue = part.split("="); + query[keyValue[0]] = keyValue[1] ? keyValue[1] : null; + } + return query; + }, + percent: (count, total) => { + const percent = Math.floor((count / total) * 10000) / 100; + if (!percent) { + return 0; + } + return percent; + }, + saveBlobAsFile: (blob, filename) => { + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.style.display = "none"; + document.body.appendChild(a); + a.href = url; + a.download = filename; + a.click(); + document.body.removeChild(a); + }, + millisToTimeString(totalMilliseconds) { + let milliseconds = (totalMilliseconds % 1000) + ""; + milliseconds = milliseconds.padStart(3, "0"); + let seconds = (Math.floor(totalMilliseconds / 1000) % 60) + ""; + seconds = seconds.padStart(2, "0"); + let minutes = (Math.floor(totalMilliseconds / 60000) % 60) + ""; + minutes = minutes.padStart(2, "0"); + let hours = Math.floor(totalMilliseconds / 3600000) + ""; + hours = hours.padStart(2, "0"); + return `${hours}:${minutes}:${seconds}`; + } +}; diff --git a/tests/wpt/web-platform-tests/tools/wave/export/res/wavelogo_2016.jpg b/tests/wpt/web-platform-tests/tools/wave/export/res/wavelogo_2016.jpg new file mode 100644 index 00000000000..38814095971 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/export/res/wavelogo_2016.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/network/__init__.py b/tests/wpt/web-platform-tests/tools/wave/network/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/network/api/__init__.py b/tests/wpt/web-platform-tests/tools/wave/network/api/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/network/api/api_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/api/api_handler.py new file mode 100644 index 00000000000..2b6d35cc54e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/api/api_handler.py @@ -0,0 +1,58 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import json +import sys +import traceback +import logging +try: + from urllib.parse import parse_qsl +except ImportError: + from urlparse import parse_qsl + +global logger +logger = logging.getLogger("wave-api-handler") + + +class ApiHandler(object): + def __init__(self, web_root): + self._web_root = web_root + + def set_headers(self, response, headers): + if not isinstance(response.headers, list): + response.headers = [] + for header in headers: + response.headers.append(header) + + def send_json(self, data, response, status=None): + if status is None: + status = 200 + json_string = json.dumps(data, indent=4) + response.content = json_string + self.set_headers(response, [("Content-Type", "application/json")]) + response.status = status + + def send_file(self, blob, file_name, response): + self.set_headers(response, + [("Content-Disposition", + "attachment;filename=" + file_name)]) + response.content = blob + + def send_zip(self, data, file_name, response): + response.headers = [("Content-Type", "application/x-compressed")] + self.send_file(data, file_name, response) + + def parse_uri(self, request): + path = request.url_parts.path + if self._web_root is not None: + path = path[len(self._web_root):] + + uri_parts = list(filter(None, path.split("/"))) + return uri_parts + + def parse_query_parameters(self, request): + return dict(parse_qsl(request.url_parts.query)) + + def handle_exception(self, message): + info = sys.exc_info() + traceback.print_tb(info[2]) + logger.error("{}: {}: {}".format(message, info[0].__name__, info[1].args[0])) diff --git a/tests/wpt/web-platform-tests/tools/wave/network/api/results_api_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/api/results_api_handler.py new file mode 100644 index 00000000000..c52eee56ada --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/api/results_api_handler.py @@ -0,0 +1,225 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import json + +from .api_handler import ApiHandler +from ...data.exceptions.duplicate_exception import DuplicateException +from ...data.exceptions.invalid_data_exception import InvalidDataException + + +class ResultsApiHandler(ApiHandler): + def __init__(self, results_manager, web_root): + super(ResultsApiHandler, self).__init__(web_root) + self._results_manager = results_manager + + def create_result(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + data = None + body = request.body.decode("utf-8") + if body != "": + data = json.loads(body) + + self._results_manager.create_result(token, data) + + except Exception: + self.handle_exception("Failed to create result") + response.status = 500 + + def read_results(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + results = self._results_manager.read_results(token) + + self.send_json(response=response, data=results) + + except Exception: + self.handle_exception("Failed to read results") + response.status = 500 + + def read_results_compact(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + results = self._results_manager.read_flattened_results(token) + + self.send_json(response=response, data=results) + + except Exception: + self.handle_exception("Failed to read compact results") + response.status = 500 + + def read_results_config(self, request, response): + try: + import_enabled = self._results_manager.is_import_enabled() + reports_enabled = self._results_manager.are_reports_enabled() + + self.send_json({ + "import_enabled": import_enabled, + "reports_enabled": reports_enabled + }, response) + except Exception: + self.handle_exception("Failed to read results configuration") + response.status = 500 + + def read_results_api_wpt_report_url(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + api = uri_parts[3] + + uri = self._results_manager.read_results_wpt_report_uri(token, api) + self.send_json({"uri": uri}, response) + except Exception: + self.handle_exception("Failed to read results report url") + response.status = 500 + + def read_results_api_wpt_multi_report_uri(self, request, response): + try: + uri_parts = self.parse_uri(request) + api = uri_parts[3] + query = self.parse_query_parameters(request) + tokens = query["tokens"].split(",") + uri = self._results_manager.read_results_wpt_multi_report_uri( + tokens, + api + ) + self.send_json({"uri": uri}, response) + except Exception: + self.handle_exception("Failed to read results multi report url") + response.status = 500 + + def download_results_api_json(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + api = uri_parts[3] + blob = self._results_manager.export_results_api_json(token, api) + if blob is None: + response.status = 404 + return + file_path = self._results_manager.get_json_path(token, api) + file_name = "{}-{}-{}".format( + token.split("-")[0], + api, + file_path.split("/")[-1] + ) + self.send_zip(blob, file_name, response) + except Exception: + self.handle_exception("Failed to download api json") + response.status = 500 + + def download_results_all_api_jsons(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + blob = self._results_manager.export_results_all_api_jsons(token) + file_name = token.split("-")[0] + "_results_json.zip" + self.send_zip(blob, file_name, response) + except Exception: + self.handle_exception("Failed to download all api jsons") + response.status = 500 + + def download_results(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + blob = self._results_manager.export_results(token) + if blob is None: + response.status = 404 + return + file_name = token + ".zip" + self.send_zip(blob, file_name, response) + except Exception: + self.handle_exception("Failed to download results") + response.status = 500 + + def download_results_overview(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + blob = self._results_manager.export_results_overview(token) + if blob is None: + response.status = 404 + return + file_name = token.split("-")[0] + "_results_html.zip" + self.send_zip(blob, file_name, response) + except Exception: + self.handle_exception("Failed to download results overview") + response.status = 500 + + def import_results(self, request, response): + try: + blob = request.body + token = self._results_manager.import_results(blob) + self.send_json({"token": token}, response) + except DuplicateException: + self.handle_exception("Failed to import results") + self.send_json({"error": "Session already exists!"}, response, 400) + return + except InvalidDataException: + self.handle_exception("Failed to import results") + self.send_json({"error": "Invalid input data!"}, response, 400) + return + except Exception: + self.handle_exception("Failed to import results") + response.status = 500 + + def handle_request(self, request, response): + method = request.method + uri_parts = self.parse_uri(request) + + # /api/results/ + if len(uri_parts) == 3: + if method == "POST": + if uri_parts[2] == "import": + self.import_results(request, response) + return + self.create_result(request, response) + return + + if method == "GET": + if uri_parts[2] == "config": + self.read_results_config(request, response) + return + else: + self.read_results(request, response) + return + + # /api/results// + if len(uri_parts) == 4: + function = uri_parts[3] + if method == "GET": + if function == "compact": + self.read_results_compact(request, response) + return + if function == "reporturl": + return self.read_results_api_wpt_multi_report_uri(request, + response) + if function == "json": + self.download_results_all_api_jsons(request, response) + return + if function == "export": + self.download_results(request, response) + return + if function == "overview": + self.download_results_overview(request, response) + return + + # /api/results/// + if len(uri_parts) == 5: + function = uri_parts[4] + if method == "GET": + if function == "reporturl": + self.read_results_api_wpt_report_url(request, response) + return + if function == "json": + self.download_results_api_json(request, response) + return + + response.status = 404 diff --git a/tests/wpt/web-platform-tests/tools/wave/network/api/sessions_api_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/api/sessions_api_handler.py new file mode 100644 index 00000000000..b6484566730 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/api/sessions_api_handler.py @@ -0,0 +1,342 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import json +import threading + +from .api_handler import ApiHandler + +from ...utils.serializer import serialize_session +from ...data.exceptions.not_found_exception import NotFoundException +from ...data.exceptions.invalid_data_exception import InvalidDataException +from ...data.http_polling_client import HttpPollingClient + +TOKEN_LENGTH = 36 + + +class SessionsApiHandler(ApiHandler): + def __init__(self, sessions_manager, results_manager, event_dispatcher, web_root): + super(SessionsApiHandler, self).__init__(web_root) + self._sessions_manager = sessions_manager + self._results_manager = results_manager + self._event_dispatcher = event_dispatcher + + def create_session(self, request, response): + try: + config = {} + body = request.body.decode("utf-8") + if body != "": + config = json.loads(body) + tests = {} + if "tests" in config: + tests = config["tests"] + types = None + if "types" in config: + types = config["types"] + timeouts = {} + if "timeouts" in config: + timeouts = config["timeouts"] + reference_tokens = [] + if "reference_tokens" in config: + reference_tokens = config["reference_tokens"] + webhook_urls = [] + if "webhook_urls" in config: + webhook_urls = config["webhook_urls"] + user_agent = request.headers[b"user-agent"].decode("utf-8") + labels = [] + if "labels" in config: + labels = config["labels"] + expiration_date = None + if "expiration_date" in config: + expiration_date = config["expiration_date"] + + session = self._sessions_manager.create_session( + tests, + types, + timeouts, + reference_tokens, + webhook_urls, + user_agent, + labels, + expiration_date + ) + + self.send_json({"token": session.token}, response) + except InvalidDataException: + self.handle_exception("Failed to create session") + self.send_json({"error": "Invalid input data!"}, response, 400) + + except Exception: + self.handle_exception("Failed to create session") + response.status = 500 + + def read_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + session = self._sessions_manager.read_session(token) + if session is None: + response.status = 404 + return + + data = serialize_session(session) + + del data["pending_tests"] + del data["running_tests"] + del data["malfunctioning_tests"] + del data["test_state"] + del data["date_started"] + del data["date_finished"] + del data["status"] + + self.send_json(data, response) + except Exception: + self.handle_exception("Failed to read session") + response.status = 500 + + def read_session_status(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + session = self._sessions_manager.read_session_status(token) + if session is None: + response.status = 404 + return + data = serialize_session(session) + + del data["tests"] + del data["pending_tests"] + del data["running_tests"] + del data["malfunctioning_tests"] + del data["types"] + del data["test_state"] + del data["last_completed_test"] + del data["user_agent"] + del data["timeouts"] + del data["browser"] + del data["is_public"] + del data["reference_tokens"] + del data["webhook_urls"] + + self.send_json(data, response) + except Exception: + self.handle_exception("Failed to read session status") + response.status = 500 + + def read_public_sessions(self, request, response): + try: + session_tokens = self._sessions_manager.read_public_sessions() + + self.send_json(session_tokens, response) + except Exception: + self.handle_exception("Failed to read public sessions") + response.status = 500 + + def update_session_configuration(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + config = {} + body = request.body.decode("utf-8") + if body != "": + config = json.loads(body) + + tests = {} + if "tests" in config: + tests = config["tests"] + types = None + if "types" in config: + types = config["types"] + timeouts = {} + if "timeouts" in config: + timeouts = config["timeouts"] + reference_tokens = [] + if "reference_tokens" in config: + reference_tokens = config["reference_tokens"] + webhook_urls = [] + if "webhook_urls" in config: + webhook_urls = config["webhook_urls"] + + self._sessions_manager.update_session_configuration( + token, + tests, + types, + timeouts, + reference_tokens, + webhook_urls + ) + except NotFoundException: + self.handle_exception("Failed to update session configuration") + response.status = 404 + except Exception: + self.handle_exception("Failed to update session configuration") + response.status = 500 + + def update_labels(self, request, response): + try: + uri_parts = self.parse_uri(request) + # convert unicode to ascii to get a text type, ignore special chars + token = uri_parts[2] + body = request.body.decode("utf-8") + labels = None + if body != "": + labels = json.loads(body) + if "labels" in labels: + labels = labels["labels"] + + self._sessions_manager.update_labels(token=token, labels=labels) + except Exception: + self.handle_exception("Failed to update labels") + response.status = 500 + + def delete_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + session = self._sessions_manager.read_session(token) + if session is None: + response.status = 404 + return + + self._sessions_manager.delete_session(token) + self._results_manager.delete_results(token) + except Exception: + self.handle_exception("Failed to delete session") + response.status = 500 + + def start_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + self._sessions_manager.start_session(token) + except Exception: + self.handle_exception("Failed to start session") + response.status = 500 + + def pause_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + self._sessions_manager.pause_session(token) + except Exception: + self.handle_exception("Failed to pause session") + response.status = 500 + + def stop_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + self._sessions_manager.stop_session(token) + except Exception: + self.handle_exception("Failed to stop session") + response.status = 500 + + def resume_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + resume_token = None + body = request.body.decode("utf-8") + if body != "": + resume_token = json.loads(body)["resume_token"] + + self._sessions_manager.resume_session(token, resume_token) + except Exception: + self.handle_exception("Failed to resume session") + response.status = 500 + + def find_session(self, request, response): + try: + uri_parts = self.parse_uri(request) + fragment = uri_parts[2] + token = self._sessions_manager.find_token(fragment) + if token is None: + response.status = 404 + return + self.send_json({"token": token}, response) + except Exception: + self.handle_exception("Failed to find session") + response.status = 500 + + def register_event_listener(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + event = threading.Event() + http_polling_client = HttpPollingClient(token, event) + self._event_dispatcher.add_session_client(http_polling_client) + + event.wait() + + message = http_polling_client.message + self.send_json(data=message, response=response) + except Exception: + self.handle_exception("Failed to register event listener") + response.status = 500 + + def handle_request(self, request, response): + method = request.method + uri_parts = self.parse_uri(request) + + # /api/sessions + if len(uri_parts) == 2: + if method == "POST": + self.create_session(request, response) + return + + # /api/sessions/ + if len(uri_parts) == 3: + function = uri_parts[2] + if method == "GET": + if function == "public": + self.read_public_sessions(request, response) + return + if len(function) != TOKEN_LENGTH: + self.find_session(request, response) + return + self.read_session(request, response) + return + if method == "PUT": + self.update_session_configuration(request, response) + return + if method == "DELETE": + self.delete_session(request, response) + return + + # /api/sessions// + if len(uri_parts) == 4: + function = uri_parts[3] + if method == "GET": + if function == "status": + self.read_session_status(request, response) + return + if function == "events": + self.register_event_listener(request, response) + return + if method == "POST": + if function == "start": + self.start_session(request, response) + return + if function == "pause": + self.pause_session(request, response) + return + if function == "stop": + self.stop_session(request, response) + return + if function == "resume": + self.resume_session(request, response) + return + if method == "PUT": + if function == "labels": + self.update_labels(request, response) + return + + response.status = 404 diff --git a/tests/wpt/web-platform-tests/tools/wave/network/api/tests_api_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/api/tests_api_handler.py new file mode 100644 index 00000000000..6c9357a32c5 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/api/tests_api_handler.py @@ -0,0 +1,287 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import json +try: + from urllib.parse import urlunsplit +except ImportError: + from urlparse import urlunsplit + +from .api_handler import ApiHandler +from ...utils.serializer import serialize_session +from ...data.session import PAUSED, COMPLETED, ABORTED, PENDING, RUNNING + +DEFAULT_LAST_COMPLETED_TESTS_COUNT = 5 +DEFAULT_LAST_COMPLETED_TESTS_STATUS = ["ALL"] + + +class TestsApiHandler(ApiHandler): + def __init__( + self, + wpt_port, + wpt_ssl_port, + tests_manager, + sessions_manager, + hostname, + web_root, + test_loader + ): + super(TestsApiHandler, self).__init__(web_root) + self._tests_manager = tests_manager + self._sessions_manager = sessions_manager + self._wpt_port = wpt_port + self._wpt_ssl_port = wpt_ssl_port + self._hostname = hostname + self._web_root = web_root + self._test_loader = test_loader + + def read_tests(self, response): + tests = self._tests_manager.read_tests() + self.send_json(tests, response) + + def read_session_tests(self, request, response): + uri_parts = self.parse_uri(request) + token = uri_parts[2] + session = self._sessions_manager.read_session(token) + + if session is None: + response.status = 404 + return + + data = serialize_session(session) + tests = { + "token": token, + "pending_tests": data["pending_tests"], + "running_tests": data["running_tests"] + } + self.send_json(tests, response) + + def read_next_test(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + hostname = self._hostname + + session = self._sessions_manager.read_session(token) + if session is None: + response.status = 404 + return + + if session.status == PAUSED: + url = self._generate_wave_url( + hostname=hostname, + uri="pause.html", + token=token + ) + self.send_json({"next_test": url}, response) + return + if session.status == COMPLETED or session.status == ABORTED: + url = self._generate_wave_url( + hostname=hostname, + uri="finish.html", + token=token + ) + self.send_json({"next_test": url}, response) + return + if session.status == PENDING: + url = self._generate_wave_url( + hostname=hostname, + uri="newsession.html", + token=token + ) + self.send_json({"next_test": url}, response) + return + + test = self._tests_manager.next_test(session) + + if test is None: + if session.status != RUNNING: + return + url = self._generate_wave_url( + hostname=hostname, + uri="finish.html", + token=token + ) + self.send_json({"next_test": url}, response) + self._sessions_manager.complete_session(token) + return + + test_timeout = self._tests_manager.get_test_timeout( + test=test, session=session) + url = self._generate_test_url( + test=test, + token=token, + test_timeout=test_timeout, + hostname=hostname) + + self.send_json({ + "next_test": url + }, response) + except Exception: + self.handle_exception("Failed to read next test") + response.status = 500 + + def read_last_completed(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + query = self.parse_query_parameters(request) + count = None + if "count" in query: + count = query["count"] + else: + count = DEFAULT_LAST_COMPLETED_TESTS_COUNT + + status = None + if "status" in query: + status = query["status"].split(",") + else: + status = DEFAULT_LAST_COMPLETED_TESTS_STATUS + + completed_tests = self._tests_manager.read_last_completed_tests( + token, count) + tests = {} + for one_status in status: + one_status = one_status.lower() + if one_status == "pass": + tests["pass"] = completed_tests["pass"] + continue + if one_status == "fail": + tests["fail"] = completed_tests["fail"] + continue + if one_status == "timeout": + tests["timeout"] = completed_tests["timeout"] + continue + if one_status == "all": + tests["pass"] = completed_tests["pass"] + tests["fail"] = completed_tests["fail"] + tests["timeout"] = completed_tests["timeout"] + break + self.send_json(data=tests, response=response) + except Exception: + self.handle_exception("Failed to read last completed tests") + response.status = 500 + + def read_malfunctioning(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + tm = self._tests_manager + malfunctioning_tests = tm.read_malfunctioning_tests(token) + + self.send_json(data=malfunctioning_tests, response=response) + except Exception: + self.handle_exception("Failed to read malfunctioning tests") + response.status = 500 + + def update_malfunctioning(self, request, response): + try: + uri_parts = self.parse_uri(request) + token = uri_parts[2] + + data = None + body = request.body.decode("utf-8") + if body != "": + data = json.loads(body) + + self._tests_manager.update_malfunctioning_tests(token, data) + except Exception: + self.handle_exception("Failed to update malfunctioning tests") + response.status = 500 + + def read_available_apis(self, request, response): + try: + apis = self._test_loader.get_apis() + self.send_json(apis, response) + except Exception: + self.handle_exception("Failed to read available APIs") + response.status = 500 + + def handle_request(self, request, response): + method = request.method + uri_parts = self.parse_uri(request) + + # /api/tests + if len(uri_parts) == 2: + if method == "GET": + self.read_tests(response) + return + + # /api/tests/ + if len(uri_parts) == 3: + if method == "GET": + if uri_parts[2] == "apis": + self.read_available_apis(request, response) + return + self.read_session_tests(request, response) + return + + # /api/tests// + if len(uri_parts) == 4: + function = uri_parts[3] + if method == "GET": + if function == "next": + self.read_next_test(request, response) + return + if function == "last_completed": + self.read_last_completed(request, response) + return + if function == "malfunctioning": + self.read_malfunctioning(request, response) + return + if method == "PUT": + if function == "malfunctioning": + self.update_malfunctioning(request, response) + return + + response.status = 404 + + def _generate_wave_url(self, hostname, uri, token): + if self._web_root is not None: + uri = self._web_root + uri + + return self._generate_url( + hostname=hostname, + uri=uri, + port=self._wpt_port, + query="token=" + token + ) + + def _generate_test_url(self, hostname, test, token, test_timeout): + protocol = "http" + port = self._wpt_port + + if "https" in test: + protocol = "https" + port = self._wpt_ssl_port + + query = "token={}&timeout={}&https_port={}&web_root={}".format( + token, + test_timeout, + self._wpt_ssl_port, + self._web_root + ) + + return self._generate_url( + protocol=protocol, + hostname=hostname, + port=port, + uri=test, + query=query + ) + + def _generate_url(self, + hostname, + port=None, + uri=None, + query=None, + protocol=None): + if port is None: + port = 80 + if uri is None: + uri = "/" + if query is None: + query = "" + if protocol is None: + protocol = "http" + return urlunsplit([protocol, "{}:{}".format(hostname, port), uri, query, '']) diff --git a/tests/wpt/web-platform-tests/tools/wave/network/http_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/http_handler.py new file mode 100644 index 00000000000..324524679a0 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/http_handler.py @@ -0,0 +1,102 @@ +from __future__ import unicode_literals +try: + import http.client as httplib +except ImportError: + import httplib +import sys +import traceback + + +class HttpHandler(object): + def __init__( + self, + static_handler=None, + sessions_api_handler=None, + tests_api_handler=None, + results_api_handler=None, + http_port=None, + web_root=None + ): + self.static_handler = static_handler + self.sessions_api_handler = sessions_api_handler + self.tests_api_handler = tests_api_handler + self.results_api_handler = results_api_handler + self._http_port = http_port + self._web_root = web_root + + def handle_request(self, request, response): + response.headers = [ + ("Access-Control-Allow-Origin", "*"), + ("Access-Control-Allow-Headers", "*"), + ("Access-Control-Allow-Methods", "*") + ] + if request.method == "OPTIONS": + return + + path = self._remove_web_root(request.request_path) + + is_api_call = False + for index, part in enumerate(path.split("/")): + if index > 2: + break + if part != "api": + continue + + is_api_call = True + + if (is_api_call): + if request.url_parts.scheme == "https": + self._proxy(request, response) + return + self.handle_api(request, response) + else: + self.handle_static_file(request, response) + + def handle_api(self, request, response): + path = self._remove_web_root(request.request_path) + api_name = path.split("/")[1] + + if api_name is None: + return + + if api_name == "sessions": + self.sessions_api_handler.handle_request(request, response) + return + if api_name == "tests": + self.tests_api_handler.handle_request(request, response) + return + if api_name == "results": + self.results_api_handler.handle_request(request, response) + return + + def handle_static_file(self, request, response): + self.static_handler.handle_request(request, response) + + def _remove_web_root(self, path): + if self._web_root is not None: + path = path[len(self._web_root):] + return path + + + def _proxy(self, request, response): + host = 'localhost' + port = str(self._http_port) + uri = request.url_parts.path + uri = uri + "?" + request.url_parts.query + data = request.raw_input.read(request.headers.get('Content-Length')) + method = request.method + + try: + proxy_connection = httplib.HTTPConnection(host, port) + proxy_connection.request(method, uri, data, request.headers) + proxy_response = proxy_connection.getresponse() + response.content = proxy_response.read() + response.headers = proxy_response.getheaders() + response.status = proxy_response.status + + except IOError: + info = sys.exc_info() + traceback.print_tb(info[2]) + print("Failed to perform proxy request: " + + info[0].__name__ + ": " + str(info[1].args[0])) + response.status = 500 diff --git a/tests/wpt/web-platform-tests/tools/wave/network/static_handler.py b/tests/wpt/web-platform-tests/tools/wave/network/static_handler.py new file mode 100644 index 00000000000..0b666eef5a3 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/network/static_handler.py @@ -0,0 +1,55 @@ +from __future__ import with_statement +from __future__ import absolute_import +from __future__ import unicode_literals +import os +from io import open + + +class StaticHandler(object): + def __init__(self, web_root, http_port, https_port): + self.static_dir = os.path.join( + os.getcwd(), "tools/wave/www") + self._web_root = web_root + self._http_port = http_port + self._https_port = https_port + + def handle_request(self, request, response): + file_path = request.request_path + + if self._web_root is not None: + file_path = file_path[len(self._web_root):] + + if file_path == "." or file_path == "./" or file_path == "": + file_path = "index.html" + + file_path = file_path.split("?")[0] + file_path = os.path.join(self.static_dir, file_path) + + headers = [] + + content_types = { + "html": "text/html", + "js": "text/javascript", + "css": "text/css", + "jpg": "image/jpeg", + "jpeg": "image/jpeg", + "ttf": "font/ttf", + "woff": "font/woff", + "woff2": "font/woff2" + } + + headers.append( + ("Content-Type", content_types[file_path.split(".")[-1]])) + + data = None + with open(file_path, "rb") as file: + data = file.read() + + if file_path.split("/")[-1] == "wave-service.js": + data = data.decode("UTF-8") + data = data.replace("{{WEB_ROOT}}", str(self._web_root)) + data = data.replace("{{HTTP_PORT}}", str(self._http_port)) + data = data.replace("{{HTTPS_PORT}}", str(self._https_port)) + + response.content = data + response.headers = headers diff --git a/tests/wpt/web-platform-tests/tools/wave/requirements.txt b/tests/wpt/web-platform-tests/tools/wave/requirements.txt new file mode 100644 index 00000000000..0383e084087 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/requirements.txt @@ -0,0 +1 @@ +ua-parser==0.8.0 \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/resources/testharnessreport.js b/tests/wpt/web-platform-tests/tools/wave/resources/testharnessreport.js new file mode 100644 index 00000000000..f6ac75f6697 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/resources/testharnessreport.js @@ -0,0 +1,277 @@ +/* global add_completion_callback */ +/* global setup */ + +/* + * This file is intended for vendors to implement code needed to integrate + * testharness.js tests with their own test systems. + * + * Typically test system integration will attach callbacks when each test has + * run, using add_result_callback(callback(test)), or when the whole test file + * has completed, using + * add_completion_callback(callback(tests, harness_status)). + * + * For more documentation about the callback functions and the + * parameters they are called with see testharness.js + */ + +/* + * If the query parameter token is available means that the test was loaded by + * the WAVE test runner and the results need to be reported to the server using + * the provided token to identify the session associated this token. + */ +console.log("ARDVAARD") +if (location.search && location.search.indexOf("token=") != -1) { + var __WAVE__HOSTNAME = location.hostname; + var __WAVE__PORT = location.port; + var __WAVE__PROTOCOL = location.protocol.replace(/:/, ""); + var __WAVE__QUERY = location.search; + if (!__WAVE__QUERY) __WAVE__QUERY = "?"; + var match = __WAVE__QUERY.match(/https_port=(\d+)/); + var __HTTPS_PORT = parseInt(match && match[1] ? match[1] : 443); + match = __WAVE__QUERY.match(/timeout=(\d+)/); + var __WAVE__TIMEOUT = parseInt(match && match[1] ? match[1] : 65000); + match = __WAVE__QUERY.match(/web_root=(.+)/); + var __WAVE__WEB_ROOT = match && match[1] ? match[1] : "/wave/"; + console.log("\n\n\n\n\n") + console.log(match) + console.log(__WAVE__WEB_ROOT) + match = __WAVE__QUERY.match(/token=([^&]+)/); + var __WAVE__TOKEN = match ? match[1] : null; + var __WAVE__TEST = location.pathname; + var nextUrl = null; + var resultSent = false; + var screenConsole; + + try { + var documentRoot = document.body ? document.body : document.documentElement; + documentRoot.style["background-color"] = "#FFF"; + window.open = function () { + logToConsole( + "window.open() is overridden in testharnessreport.js and has not effect" + ); + var dummyWin = { + close: function () { + logToConsole( + "dummyWindow.close() in testharnessreport.js and has not effect" + ); + } + }; + return dummyWin; + }; + window.close = function () { + logToConsole( + "window.close() is overridden in testharnessreport.js and has not effect" + ); + }; + } catch (err) {} + + setTimeout(function () { + loadNext(); + }, __WAVE__TIMEOUT); + + function logToConsole() { + var text = ""; + for (var i = 0; i < arguments.length; i++) { + text += arguments[i] + " "; + } + if (console && console.log) { + console.log(text); + } + if (screenConsole) { + try { + text = text.replace(/ /gm, " "); + text = text.replace(/\n/gm, "
"); + screenConsole.innerHTML += "
" + text; + } catch (error) { + screenConsole.innerText += "\n" + text; + } + } + } + + function dump_and_report_test_results(tests, status) { + var results_element = document.createElement("script"); + results_element.type = "text/json"; + results_element.id = "__testharness__results__"; + var test_results = tests.map(function (x) { + return { + name: x.name, + status: x.status, + message: x.message, + stack: x.stack + }; + }); + var data = { + test: window.location.href, + tests: test_results, + status: status.status, + message: status.message, + stack: status.stack + }; + results_element.textContent = JSON.stringify(data); + + // To avoid a HierarchyRequestError with XML documents, ensure that 'results_element' + // is inserted at a location that results in a valid document. + var parent = document.body ? + document.body // is required in XHTML documents + : + document.documentElement; // fallback for optional in HTML5, SVG, etc. + + parent.appendChild(results_element); + + screenConsole = document.createElement("div"); + screenConsole.setAttribute("id", "console"); + screenConsole.setAttribute("style", "font-family: monospace; padding: 5px"); + parent.appendChild(screenConsole); + window.onerror = logToConsole; + + finishWptTest(data); + } + + function finishWptTest(data) { + logToConsole("Creating result ..."); + data.test = __WAVE__TEST; + createResult( + __WAVE__TOKEN, + data, + function () { + logToConsole("Result created."); + loadNext(); + }, + function () { + logToConsole("Failed to create result."); + logToConsole("Trying alternative method ..."); + createResultAlt(__WAVE__TOKEN, data); + } + ); + } + + function loadNext() { + logToConsole("Loading next test ..."); + readNextTest( + __WAVE__TOKEN, + function (url) { + logToConsole("Redirecting to " + url); + location.href = url; + }, + function () { + logToConsole("Could not load next test."); + logToConsole("Trying alternative method ..."); + readNextAlt(__WAVE__TOKEN); + } + ); + } + + function readNextTest(token, onSuccess, onError) { + sendRequest( + "GET", + "api/tests/" + token + "/next", + null, + null, + function (response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.next_test); + }, + onError + ); + } + + function readNextAlt(token) { + location.href = getWaveUrl("next.html?token=" + token); + } + + function createResult(token, result, onSuccess, onError) { + sendRequest( + "POST", + "api/results/" + token, { + "Content-Type": "application/json" + }, + JSON.stringify(result), + function () { + onSuccess(); + }, + onError + ); + } + + function createResultAlt(token, result) { + location.href = __WAVE__WEB_ROOT + "submitresult.html" + + "?token=" + token + + "&result=" + encodeURIComponent(JSON.stringify(result)); + } + + function sendRequest(method, uri, headers, data, onSuccess, onError) { + var url = getWaveUrl(uri); + var xhr = new XMLHttpRequest(); + xhr.addEventListener("load", function () { + onSuccess(xhr.response); + }); + xhr.addEventListener("error", function () { + if (onError) onError(); + }); + logToConsole("Sending", method, 'request to "' + url + '"'); + xhr.open(method, url, true); + if (headers) { + for (var header in headers) { + xhr.setRequestHeader(header, headers[header]); + } + } + xhr.send(data); + } + + function getWaveUrl(uri) { + var url = __WAVE__WEB_ROOT + uri; + console.log(url) + return url; + } + + add_completion_callback(dump_and_report_test_results); + +} else { + function dump_test_results(tests, status) { + var results_element = document.createElement("script"); + results_element.type = "text/json"; + results_element.id = "__testharness__results__"; + var test_results = tests.map(function (x) { + return { + name: x.name, + status: x.status, + message: x.message, + stack: x.stack + } + }); + var data = { + test: window.location.href, + tests: test_results, + status: status.status, + message: status.message, + stack: status.stack + }; + results_element.textContent = JSON.stringify(data); + + // To avoid a HierarchyRequestError with XML documents, ensure that 'results_element' + // is inserted at a location that results in a valid document. + var parent = document.body + ? document.body // is required in XHTML documents + : document.documentElement; // fallback for optional in HTML5, SVG, etc. + + parent.appendChild(results_element); + } + + add_completion_callback(dump_test_results); + + /* If the parent window has a testharness_properties object, + * we use this to provide the test settings. This is used by the + * default in-browser runner to configure the timeout and the + * rendering of results + */ + try { + if (window.opener && "testharness_properties" in window.opener) { + /* If we pass the testharness_properties object as-is here without + * JSON stringifying and reparsing it, IE fails & emits the message + * "Could not complete the operation due to error 80700019". + */ + setup(JSON.parse(JSON.stringify(window.opener.testharness_properties))); + } + } catch (e) {} + // vim: set expandtab shiftwidth=4 tabstop=4: +} diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/__init__.py b/tests/wpt/web-platform-tests/tools/wave/testing/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/event_dispatcher.py b/tests/wpt/web-platform-tests/tools/wave/testing/event_dispatcher.py new file mode 100644 index 00000000000..9540df02036 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/event_dispatcher.py @@ -0,0 +1,41 @@ +from __future__ import unicode_literals + +STATUS_EVENT = "status" +RESUME_EVENT = "resume" +TEST_COMPLETED_EVENT = "test_completed" + + +class EventDispatcher(object): + def __init__(self): + self._clients = {} + + def add_session_client(self, client): + token = client.session_token + if token not in self._clients: + self._clients[token] = [] + self._clients[token].append(client) + + def remove_session_client(self, client_to_delete): + if client_to_delete is None: + return + token = client_to_delete.session_token + if token not in self._clients: + return + + for client in self._clients[token]: + if client.session_token == client_to_delete.session_token: + self._clients.remove(client) + break + if len(self._clients[token]) == 0: + del self._clients[token] + + def dispatch_event(self, token, event_type, data): + if token not in self._clients: + return + event = { + "type": event_type, + "data": data + } + + for client in self._clients[token]: + client.send_message(event) diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/results_manager.py b/tests/wpt/web-platform-tests/tools/wave/testing/results_manager.py new file mode 100644 index 00000000000..aae1900d34a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/results_manager.py @@ -0,0 +1,628 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import os +import shutil +import re +import json +import hashlib +import zipfile +import time + +from ..utils.user_agent_parser import parse_user_agent, abbreviate_browser_name +from ..utils.serializer import serialize_session +from ..utils.deserializer import deserialize_session +from ..data.exceptions.invalid_data_exception import InvalidDataException +from ..data.exceptions.duplicate_exception import DuplicateException +from ..data.exceptions.not_found_exception import NotFoundException +from ..data.exceptions.permission_denied_exception import PermissionDeniedException +from .wpt_report import generate_report, generate_multi_report +from ..data.session import COMPLETED + +WAVE_SRC_DIR = "./tools/wave" + + +class ResultsManager(object): + def initialize( + self, + results_directory_path, + sessions_manager, + tests_manager, + import_enabled, + reports_enabled, + persisting_interval + ): + self._results_directory_path = results_directory_path + self._sessions_manager = sessions_manager + self._tests_manager = tests_manager + self._import_enabled = import_enabled + self._reports_enabled = reports_enabled + self._results = {} + self._persisting_interval = persisting_interval + + def create_result(self, token, data): + result = self.prepare_result(data) + test = result["test"] + + session = self._sessions_manager.read_session(token) + + if session is None: + return + if not self._sessions_manager.test_in_session(test, session): + return + if not self._sessions_manager.is_test_running(test, session): + return + self._tests_manager.complete_test(test, session) + self._push_to_cache(token, result) + self._update_test_state(result, session) + + session.last_completed_test = test + session.recent_completed_count += 1 + self._sessions_manager.update_session(session) + + api = next((p for p in test.split("/") if p != ""), None) + if session.recent_completed_count >= self._persisting_interval \ + or self._sessions_manager.is_api_complete(api, session): + self.persist_session(session) + + if not self._sessions_manager.is_api_complete(api, session): + return + self.generate_report(token, api) + + test_state = session.test_state + apis = list(test_state.keys()) + all_apis_complete = True + for api in apis: + if not self._sessions_manager.is_api_complete(api, session): + all_apis_complete = False + if not all_apis_complete: + return + self._sessions_manager.complete_session(token) + self.create_info_file(session) + + def read_results(self, token, filter_path=None): + filter_api = None + if filter_path is not None: + filter_api = next((p for p in filter_path.split("/") + if p is not None), None) + cached_results = self._read_from_cache(token) + persisted_results = self.load_results(token) + results = self._combine_results_by_api(cached_results, + persisted_results) + + filtered_results = {} + + for api in results: + if filter_api is not None and api.lower() != filter_api.lower(): + continue + for result in results[api]: + if filter_path is not None: + pattern = re.compile("^" + filter_path.replace(".", "")) + if pattern.match(result["test"].replace(".", "")) \ + is None: + continue + if api not in filtered_results: + filtered_results[api] = [] + filtered_results[api].append(result) + + return filtered_results + + def read_flattened_results(self, token): + session = self._sessions_manager.read_session(token) + return session.test_state + + def _update_test_state(self, result, session): + api = next((p for p in result["test"].split("/") if p != ""), None) + if "subtests" not in result: + if result["status"] == "OK": + session.test_state[api]["pass"] += 1 + elif result["status"] == "ERROR": + session.test_state[api]["fail"] += 1 + elif result["status"] == "TIMEOUT": + session.test_state[api]["timeout"] += 1 + elif result["status"] == "NOTRUN": + session.test_state[api]["not_run"] += 1 + else: + for test in result["subtests"]: + if test["status"] == "PASS": + session.test_state[api]["pass"] += 1 + elif test["status"] == "FAIL": + session.test_state[api]["fail"] += 1 + elif test["status"] == "TIMEOUT": + session.test_state[api]["timeout"] += 1 + elif test["status"] == "NOTRUN": + session.test_state[api]["not_run"] += 1 + + session.test_state[api]["complete"] += 1 + self._sessions_manager.update_session(session) + + def parse_test_state(self, results): + test_state = {} + for api in list(results.keys()): + test_state[api] = { + "pass": 0, + "fail": 0, + "timeout": 0, + "not_run": 0, + "total": len(results[api]), + "complete": 0, + } + for result in results[api]: + if "subtests" not in result: + if result["status"] == "OK": + test_state[api]["pass"] += 1 + elif result["status"] == "ERROR": + test_state[api]["fail"] += 1 + elif result["status"] == "TIMEOUT": + test_state[api]["timeout"] += 1 + elif result["status"] == "NOTRUN": + test_state[api]["not_run"] += 1 + else: + for test in result["subtests"]: + if test["status"] == "PASS": + test_state[api]["pass"] += 1 + elif test["status"] == "FAIL": + test_state[api]["fail"] += 1 + elif test["status"] == "TIMEOUT": + test_state[api]["timeout"] += 1 + elif test["status"] == "NOTRUN": + test_state[api]["not_run"] += 1 + test_state[api]["complete"] += 1 + return test_state + + def read_common_passed_tests(self, tokens=None): + if tokens is None or len(tokens) == 0: + return None + + session_results = [] + + for token in tokens: + session_result = self.read_results(token) + session_results.append(session_result) + + passed_tests = {} + failed_tests = {} + + for result in session_results: + for api in result: + if api not in passed_tests: + passed_tests[api] = [] + if api not in failed_tests: + failed_tests[api] = [] + + for api_result in result[api]: + passed = True + for subtest in api_result["subtests"]: + if subtest["status"] == "PASS": + continue + passed = False + break + + test = api_result["test"] + + if passed: + if test in failed_tests[api]: + continue + if test in passed_tests[api]: + continue + passed_tests[api].append(test) + else: + if test in passed_tests[api]: + passed_tests[api].remove(test) + if test in failed_tests[api]: + continue + failed_tests[api].append(test) + + def read_results_wpt_report_uri(self, token, api): + api_directory = os.path.join(self._results_directory_path, token, api) + if not os.path.isdir(api_directory): + return None + return "/results/{}/{}/all.html".format(token, api) + + def read_results_wpt_multi_report_uri(self, tokens, api): + comparison_directory_name = self.get_comparison_identifier(tokens) + + relative_api_directory_path = os.path.join(comparison_directory_name, + api) + + api_directory_path = os.path.join( + self._results_directory_path, + relative_api_directory_path + ) + + if not os.path.isdir(api_directory_path): + self.generate_multi_report(tokens, api) + + return "/results/{}/all.html".format(relative_api_directory_path) + + def delete_results(self, token): + results_directory = os.path.join(self._results_directory_path, token) + if not os.path.isdir(results_directory): + return + shutil.rmtree(results_directory) + + def persist_session(self, session): + token = session.token + if token not in self._results: + return + for api in list(self._results[token].keys())[:]: + self.save_api_results(token, api) + self.create_info_file(session) + self._clear_cache_api(token, api) + session.recent_completed_count = 0 + self._sessions_manager.update_session(session) + + def load_results(self, token): + results_directory = os.path.join(self._results_directory_path, token) + if not os.path.isdir(results_directory): + return {} + results = {} + apis = os.listdir(results_directory) + for api in apis: + api_directory = os.path.join(results_directory, api) + if not os.path.isdir(api_directory): + continue + files = os.listdir(api_directory) + for file_name in files: + if re.match(r"\w\w\d{1,3}\.json", file_name) is None: + continue + file_path = os.path.join(api_directory, file_name) + data = None + with open(file_path, "r") as file: + data = file.read() + result = json.loads(data) + results[api] = result["results"] + break + return results + + def _push_to_cache(self, token, result): + if token is None: + return + if token not in self._results: + self._results[token] = {} + test = result["test"] + api = next((p for p in test.split("/") if p != ""), None) + if api not in self._results[token]: + self._results[token][api] = [] + self._results[token][api].append(result) + + def _read_from_cache(self, token): + if token is None: + return [] + if token not in self._results: + return [] + return self._results[token] + + def _clear_cache_api(self, token, api): + if token is None: + return + if token not in self._results: + return + if api not in self._results[token]: + return + del self._results[token][api] + + def _combine_results_by_api(self, result_a, result_b): + combined_result = {} + for api in result_a: + if api in result_b: + combined_result[api] = result_a[api] + result_b[api] + else: + combined_result[api] = result_a[api] + + for api in result_b: + if api in combined_result: + continue + combined_result[api] = result_b[api] + + return combined_result + + def prepare_result(self, result): + harness_status_map = { + 0: "OK", + 1: "ERROR", + 2: "TIMEOUT", + 3: "NOTRUN", + "OK": "OK", + "ERROR": "ERROR", + "TIMEOUT": "TIMEOUT", + "NOTRUN": "NOTRUN" + } + + subtest_status_map = { + 0: "PASS", + 1: "FAIL", + 2: "TIMEOUT", + 3: "NOTRUN", + "PASS": "PASS", + "FAIL": "FAIL", + "TIMEOUT": "TIMEOUT", + "NOTRUN": "NOTRUN" + } + + if "tests" in result: + for test in result["tests"]: + test["status"] = subtest_status_map[test["status"]] + if "stack" in test: + del test["stack"] + result["subtests"] = result["tests"] + del result["tests"] + + if "stack" in result: + del result["stack"] + result["status"] = harness_status_map[result["status"]] + + return result + + def get_json_path(self, token, api): + session = self._sessions_manager.read_session(token) + api_directory = os.path.join(self._results_directory_path, token, api) + + browser = parse_user_agent(session.user_agent) + abbreviation = abbreviate_browser_name(browser["name"]) + version = browser["version"] + if "." in version: + version = version.split(".")[0] + version = version.zfill(2) + file_name = abbreviation + version + ".json" + + return os.path.join(api_directory, file_name) + + def save_api_results(self, token, api): + results = self._read_from_cache(token) + if api not in results: + return + results = results[api] + session = self._sessions_manager.read_session(token) + self._ensure_results_directory_existence(api, token, session) + + file_path = self.get_json_path(token, api) + file_exists = os.path.isfile(file_path) + + with open(file_path, "r+" if file_exists else "w") as file: + api_results = None + if file_exists: + data = file.read() + api_results = json.loads(data) + else: + api_results = {"results": []} + + api_results["results"] = api_results["results"] + results + + file.seek(0) + file.truncate() + file.write(json.dumps(api_results, indent=4, separators=(',', ': '))) + + def _ensure_results_directory_existence(self, api, token, session): + directory = os.path.join(self._results_directory_path, token, api) + if not os.path.exists(directory): + os.makedirs(directory) + + def generate_report(self, token, api): + file_path = self.get_json_path(token, api) + dir_path = os.path.dirname(file_path) + generate_report( + input_json_directory_path=dir_path, + output_html_directory_path=dir_path, + spec_name=api + ) + + def generate_multi_report(self, tokens, api): + comparison_directory_name = self.get_comparison_identifier(tokens) + + api_directory_path = os.path.join( + self._results_directory_path, + comparison_directory_name, + api + ) + + if os.path.isdir(api_directory_path): + return None + + os.makedirs(api_directory_path) + + result_json_files = [] + for token in tokens: + result_json_files.append({ + "token": token, + "path": self.get_json_path(token, api) + }) + for file in result_json_files: + if not os.path.isfile(file["path"]): + return None + generate_multi_report( + output_html_directory_path=api_directory_path, + spec_name=api, + result_json_files=result_json_files + ) + + def get_comparison_identifier(self, tokens, ref_tokens=None): + if ref_tokens is None: + ref_tokens = [] + comparison_directory = "comparison" + tokens.sort() + for token in tokens: + short_token = token.split("-")[0] + comparison_directory += "-" + short_token + hash = hashlib.sha1() + ref_tokens.sort() + for token in ref_tokens: + hash.update(token) + for token in tokens: + hash.update(token) + hash = hash.hexdigest() + comparison_directory += hash[0:8] + return comparison_directory + + def create_info_file(self, session): + token = session.token + info_file_path = os.path.join( + self._results_directory_path, + token, + "info.json" + ) + info = serialize_session(session) + del info["running_tests"] + del info["pending_tests"] + + file_content = json.dumps(info, indent=2) + with open(info_file_path, "w+") as file: + file.write(file_content) + + def export_results_api_json(self, token, api): + results = self.read_results(token) + if api in results: + return json.dumps({"results": results[api]}, indent=4) + + file_path = self.get_json_path(token, api) + if not os.path.isfile(file_path): + return None + + with open(file_path, "r") as file: + blob = file.read() + return blob + + def export_results_all_api_jsons(self, token): + self._sessions_manager.read_session(token) + results_directory = os.path.join(self._results_directory_path, token) + results = self.read_results(token) + + zip_file_name = str(time.time()) + ".zip" + zip = zipfile.ZipFile(zip_file_name, "w") + for api, result in results.iteritems(): + zip.writestr( + api + ".json", + json.dumps({"results": result}, indent=4), + zipfile.ZIP_DEFLATED + ) + + results_directory = os.path.join(self._results_directory_path, token) + if os.path.isdir(results_directory): + persisted_apis = os.listdir(results_directory) + + for api in persisted_apis: + if api in results: + continue + blob = self.export_results_api_json(token, api) + if blob is None: + continue + zip.writestr(api + ".json", blob, zipfile.ZIP_DEFLATED) + + zip.close() + + with open(zip_file_name, "r") as file: + blob = file.read() + os.remove(zip_file_name) + + return blob + + def export_results(self, token): + if token is None: + return + session = self._sessions_manager.read_session(token) + if session.status != COMPLETED: + return None + + session_results_directory = os.path.join(self._results_directory_path, + token) + if not os.path.isdir(session_results_directory): + return None + + zip_file_name = str(time.time()) + ".zip" + zip = zipfile.ZipFile(zip_file_name, "w") + for root, dirs, files in os.walk(session_results_directory): + for file in files: + file_name = os.path.join(root.split(token)[1], file) + file_path = os.path.join(root, file) + zip.write(file_path, file_name, zipfile.ZIP_DEFLATED) + zip.close() + + with open(zip_file_name, "r") as file: + blob = file.read() + os.remove(zip_file_name) + + return blob + + def export_results_overview(self, token): + session = self._sessions_manager.read_session(token) + if session is None: + raise NotFoundException("Could not find session {}".format(token)) + + tmp_file_name = str(time.time()) + ".zip" + zip = zipfile.ZipFile(tmp_file_name, "w") + + flattened_results = self.read_flattened_results(token) + results_script = "const results = " + json.dumps(flattened_results, + indent=4) + zip.writestr("results.json.js", results_script) + + session_dict = serialize_session(session) + del session_dict["running_tests"] + del session_dict["pending_tests"] + details_script = "const details = " + json.dumps(session_dict, + indent=4) + zip.writestr("details.json.js", details_script) + + for root, dirs, files in os.walk(os.path.join(WAVE_SRC_DIR, "export")): + for file in files: + file_name = os.path.join(root.split("export")[1], file) + file_path = os.path.join(root, file) + zip.write(file_path, file_name, zipfile.ZIP_DEFLATED) + + zip.close() + + with open(tmp_file_name, "r") as file: + blob = file.read() + + self.remove_tmp_files() + + return blob + + def is_import_enabled(self): + return self._import_enabled + + def are_reports_enabled(self): + return self._reports_enabled + + def load_session_from_info_file(self, info_file_path): + if not os.path.isfile(info_file_path): + return None + + with open(info_file_path, "r") as info_file: + data = info_file.read() + info_file.close() + info = json.loads(str(data)) + return deserialize_session(info) + + def import_results(self, blob): + if not self.is_import_enabled: + raise PermissionDeniedException() + tmp_file_name = "{}.zip".format(str(time.time())) + + with open(tmp_file_name, "w") as file: + file.write(blob) + + zip = zipfile.ZipFile(tmp_file_name) + if "info.json" not in zip.namelist(): + raise InvalidDataException("Invalid session ZIP!") + zipped_info = zip.open("info.json") + info = zipped_info.read() + zipped_info.close() + parsed_info = json.loads(info) + token = parsed_info["token"] + session = self._sessions_manager.read_session(token) + if session is not None: + raise DuplicateException("Session already exists!") + destination_path = os.path.join(self._results_directory_path, token) + os.makedirs(destination_path) + zip.extractall(destination_path) + self.remove_tmp_files() + self.load_results() + return token + + def remove_tmp_files(self): + files = os.listdir(".") + + for file in files: + if re.match(r"\d{10}\.\d{2}\.zip", file) is None: + continue + os.remove(file) diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/sessions_manager.py b/tests/wpt/web-platform-tests/tools/wave/testing/sessions_manager.py new file mode 100644 index 00000000000..a00623c928f --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/sessions_manager.py @@ -0,0 +1,442 @@ +from __future__ import division +from __future__ import absolute_import +from __future__ import unicode_literals +import uuid +import time +import os +import json + +from threading import Timer + +from .test_loader import AUTOMATIC, MANUAL +from ..data.session import Session, PENDING, PAUSED, RUNNING, ABORTED, COMPLETED +from ..utils.user_agent_parser import parse_user_agent +from .event_dispatcher import STATUS_EVENT, RESUME_EVENT +from ..data.exceptions.not_found_exception import NotFoundException +from ..data.exceptions.invalid_data_exception import InvalidDataException +from ..utils.deserializer import deserialize_session + +DEFAULT_TEST_TYPES = [AUTOMATIC, MANUAL] +DEFAULT_TEST_PATHS = ["/"] +DEFAULT_TEST_AUTOMATIC_TIMEOUT = 60000 +DEFAULT_TEST_MANUAL_TIMEOUT = 300000 + + +class SessionsManager(object): + def initialize(self, + test_loader, + event_dispatcher, + tests_manager, + results_directory, + results_manager): + self._test_loader = test_loader + self._sessions = {} + self._expiration_timeout = None + self._event_dispatcher = event_dispatcher + self._tests_manager = tests_manager + self._results_directory = results_directory + self._results_manager = results_manager + + def create_session( + self, + tests=None, + types=None, + timeouts=None, + reference_tokens=None, + webhook_urls=None, + user_agent=None, + labels=None, + expiration_date=None + ): + if tests is None: + tests = {} + if timeouts is None: + timeouts = {} + if reference_tokens is None: + reference_tokens = [] + if webhook_urls is None: + webhook_urls = [] + if user_agent is None: + user_agent = "" + if labels is None: + labels = [] + + if "include" not in tests: + tests["include"] = DEFAULT_TEST_PATHS + if "exclude" not in tests: + tests["exclude"] = [] + if "automatic" not in timeouts: + timeouts["automatic"] = DEFAULT_TEST_AUTOMATIC_TIMEOUT + if "manual" not in timeouts: + timeouts["manual"] = DEFAULT_TEST_MANUAL_TIMEOUT + if types is None: + types = DEFAULT_TEST_TYPES + + for type in types: + if type != "automatic" and type != "manual": + raise InvalidDataException("Unknown type '{}'".format(type)) + + token = str(uuid.uuid1()) + pending_tests = self._test_loader.get_tests( + types, + include_list=tests["include"], + exclude_list=tests["exclude"], + reference_tokens=reference_tokens) + + browser = parse_user_agent(user_agent) + + test_files_count = self._tests_manager.calculate_test_files_count( + pending_tests + ) + + test_state = {} + for api in test_files_count: + test_state[api] = { + "pass": 0, + "fail": 0, + "timeout": 0, + "not_run": 0, + "total": test_files_count[api], + "complete": 0} + + session = Session( + token=token, + tests=tests, + user_agent=user_agent, + browser=browser, + types=types, + timeouts=timeouts, + pending_tests=pending_tests, + running_tests={}, + test_state=test_state, + status=PENDING, + reference_tokens=reference_tokens, + webhook_urls=webhook_urls, + labels=labels, + expiration_date=expiration_date + ) + + self._push_to_cache(session) + if expiration_date is not None: + self._set_expiration_timer() + + return session + + def read_session(self, token): + if token is None: + return None + session = self._read_from_cache(token) + if session is None or session.test_state is None: + session = self.load_session(token) + if session is not None: + self._push_to_cache(session) + return session + + def read_session_status(self, token): + if token is None: + return None + session = self._read_from_cache(token) + if session is None: + session = self.load_session_info(token) + if session is None: + return None + if session.test_state is None: + session = self.load_session(token) + if session is not None: + self._push_to_cache(session) + return session + + def read_public_sessions(self): + self.load_all_sessions_info() + session_tokens = [] + for token in self._sessions: + session = self._sessions[token] + if not session.is_public: + continue + session_tokens.append(token) + + return session_tokens + + def update_session(self, session): + self._push_to_cache(session) + + def update_session_configuration( + self, token, tests, types, timeouts, reference_tokens, webhook_urls + ): + session = self.read_session(token) + if session is None: + raise NotFoundException("Could not find session") + if session.status != PENDING: + return + + if tests is not None: + if "include" not in tests: + tests["include"] = session.tests["include"] + if "exclude" not in tests: + tests["exclude"] = session.tests["exclude"] + if reference_tokens is None: + reference_tokens = session.reference_tokens + if types is None: + types = session.types + + pending_tests = self._test_loader.get_tests( + include_list=tests["include"], + exclude_list=tests["exclude"], + reference_tokens=reference_tokens, + types=types + ) + session.pending_tests = pending_tests + session.tests = tests + test_files_count = self._tests_manager.calculate_test_files_count( + pending_tests) + test_state = {} + for api in test_files_count: + test_state[api] = { + "pass": 0, + "fail": 0, + "timeout": 0, + "not_run": 0, + "total": test_files_count[api], + "complete": 0, + } + session.test_state = test_state + + if types is not None: + session.types = types + if timeouts is not None: + if AUTOMATIC not in timeouts: + timeouts[AUTOMATIC] = session.timeouts[AUTOMATIC] + if MANUAL not in timeouts: + timeouts[MANUAL] = session.timeouts[MANUAL] + session.timeouts = timeouts + if reference_tokens is not None: + session.reference_tokens = reference_tokens + if webhook_urls is not None: + session.webhook_urls = webhook_urls + + self._push_to_cache(session) + return session + + def update_labels(self, token, labels): + if token is None or labels is None: + return + session = self.read_session(token) + if session is None: + return + if session.is_public: + return + session.labels = labels + self._push_to_cache(session) + + def delete_session(self, token): + session = self.read_session(token) + if session is None: + return + if session.is_public is True: + return + del self._sessions[token] + + def add_session(self, session): + if session is None: + return + self._push_to_cache(session) + + def load_all_sessions(self): + if not os.path.isdir(self._results_directory): + return + tokens = os.listdir(self._results_directory) + for token in tokens: + self.load_session(token) + + def load_all_sessions_info(self): + if not os.path.isdir(self._results_directory): + return + tokens = os.listdir(self._results_directory) + for token in tokens: + if token in self._sessions: + continue + self.load_session_info(token) + + def load_session(self, token): + session = self.load_session_info(token) + if session is None: + return None + + if session.test_state is None: + results = self._results_manager.load_results(token) + test_state = self._results_manager.parse_test_state(results) + session.test_state = test_state + self._results_manager.create_info_file(session) + + self._push_to_cache(session) + return session + + def load_session_info(self, token): + result_directory = os.path.join(self._results_directory, token) + if not os.path.isdir(result_directory): + return None + info_file = os.path.join(result_directory, "info.json") + if not os.path.isfile(info_file): + return None + + info_data = None + with open(info_file, "r") as file: + info_data = file.read() + parsed_info_data = json.loads(info_data) + + session = deserialize_session(parsed_info_data) + self._push_to_cache(session) + return session + + def _push_to_cache(self, session): + self._sessions[session.token] = session + + def _read_from_cache(self, token): + if token not in self._sessions: + return None + return self._sessions[token] + + def _set_expiration_timer(self): + expiring_sessions = self._read_expiring_sessions() + if len(expiring_sessions) == 0: + return + + next_session = expiring_sessions[0] + for session in expiring_sessions: + if next_session.expiration_date > session.expiration_date: + next_session = session + + if self._expiration_timeout is not None: + self._expiration_timeout.cancel() + + timeout = next_session.expiration_date / 1000.0 - int(time.time()) + if timeout < 0: + timeout = 0 + + def handle_timeout(self): + self._delete_expired_sessions() + self._set_expiration_timer() + + self._expiration_timeout = Timer(timeout, handle_timeout, [self]) + self._expiration_timeout.start() + + def _delete_expired_sessions(self): + expiring_sessions = self._read_expiring_sessions() + now = int(time.time()) + + for session in expiring_sessions: + if session.expiration_date / 1000.0 < now: + self.delete_session(session.token) + + def _read_expiring_sessions(self): + expiring_sessions = [] + for token in self._sessions: + session = self._sessions[token] + if session.expiration_date is None: + continue + expiring_sessions.append(session) + return expiring_sessions + + def start_session(self, token): + session = self.read_session(token) + + if session is None: + return + + if session.status != PENDING and session.status != PAUSED: + return + + if session.status == PENDING: + session.date_started = int(time.time()) * 1000 + session.expiration_date = None + + session.status = RUNNING + self.update_session(session) + + self._event_dispatcher.dispatch_event( + token, + event_type=STATUS_EVENT, + data=session.status + ) + + def pause_session(self, token): + session = self.read_session(token) + if session.status != RUNNING: + return + session.status = PAUSED + self.update_session(session) + self._event_dispatcher.dispatch_event( + token, + event_type=STATUS_EVENT, + data=session.status + ) + self._results_manager.persist_session(session) + + def stop_session(self, token): + session = self.read_session(token) + if session.status == ABORTED or session.status == COMPLETED: + return + session.status = ABORTED + session.date_finished = time.time() * 1000 + self.update_session(session) + self._event_dispatcher.dispatch_event( + token, + event_type=STATUS_EVENT, + data=session.status + ) + + def resume_session(self, token, resume_token): + session = self.read_session(token) + if session.status != PENDING: + return + self._event_dispatcher.dispatch_event( + token, + event_type=RESUME_EVENT, + data=resume_token + ) + self.delete_session(token) + + def complete_session(self, token): + session = self.read_session(token) + if session.status == COMPLETED or session.status == ABORTED: + return + session.status = COMPLETED + session.date_finished = time.time() * 1000 + self.update_session(session) + self._event_dispatcher.dispatch_event( + token, + event_type=STATUS_EVENT, + data=session.status + ) + + def test_in_session(self, test, session): + return self._test_list_contains_test(test, session.pending_tests) \ + or self._test_list_contains_test(test, session.running_tests) + + def is_test_complete(self, test, session): + return not self._test_list_contains_test(test, session.pending_tests) \ + and not self._test_list_contains_test(test, session.running_tests) + + def is_test_running(self, test, session): + return self._test_list_contains_test(test, session.running_tests) + + def _test_list_contains_test(self, test, test_list): + for api in list(test_list.keys()): + if test in test_list[api]: + return True + return False + + def is_api_complete(self, api, session): + return api not in session.pending_tests \ + and api not in session.running_tests + + def find_token(self, fragment): + if len(fragment) < 8: + return None + tokens = [] + for token in self._sessions: + if token.startswith(fragment): + tokens.append(token) + if len(tokens) != 1: + return None + return tokens[0] diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/test_loader.py b/tests/wpt/web-platform-tests/tools/wave/testing/test_loader.py new file mode 100644 index 00000000000..ce48639fc03 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/test_loader.py @@ -0,0 +1,197 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +import os +import re + +AUTOMATIC = "automatic" +MANUAL = "manual" + +TEST_TYPES = [AUTOMATIC, MANUAL] + + +class TestLoader(object): + def initialize( + self, + exclude_list_file_path, + include_list_file_path, + results_manager, + api_titles + ): + self._exclude_list_file_path = exclude_list_file_path + self._include_list_file_path = include_list_file_path + self._results_manager = results_manager + self._tests = {} + self._tests[AUTOMATIC] = {} + self._tests[MANUAL] = {} + self._api_titles = api_titles + + def load_tests(self, tests): + include_list = self._load_test_list(self._include_list_file_path) + exclude_list = self._load_test_list(self._exclude_list_file_path) + + if "testharness" in tests: + self._tests[AUTOMATIC] = self._load_tests( + tests=tests["testharness"], + exclude_list=exclude_list + ) + + if "manual" in tests: + self._tests[MANUAL] = self._load_tests( + tests=tests["manual"], + include_list=include_list + ) + + for api in self._tests[AUTOMATIC]: + for test_path in self._tests[AUTOMATIC][api][:]: + if "manual" not in test_path: + continue + self._tests[AUTOMATIC][api].remove(test_path) + + if not self._is_valid_test(test_path, + include_list=include_list): + continue + + if api not in self._tests[MANUAL]: + self._tests[MANUAL][api] = [] + self._tests[MANUAL][api].append(test_path) + + def _load_tests(self, tests, exclude_list=None, include_list=None): + loaded_tests = {} + + def get_next_part(tests): + paths = [] + for test in tests: + if isinstance(tests[test], dict): + subs = get_next_part(tests[test]) + for sub in subs: + if sub is None: + continue + paths.append(test + "/" + sub) + continue + if test.endswith(".html"): + paths.append(test) + continue + if test.endswith(".js"): + for element in tests[test][1:]: + paths.append(element[0]) + continue + return paths + + test_paths = get_next_part(tests) + for test_path in test_paths: + if not test_path.startswith("/"): + test_path = "/" + test_path + if self._is_valid_test(test_path, exclude_list, include_list): + api_name = self._parse_api_name(test_path) + if api_name not in loaded_tests: + loaded_tests[api_name] = [] + loaded_tests[api_name].append(test_path) + return loaded_tests + + def _parse_api_name(self, test_path): + for part in test_path.split("/"): + if part == "": + continue + return part + + def _is_valid_test(self, test_path, exclude_list=None, include_list=None): + is_valid = True + + if include_list is not None and len(include_list) > 0: + is_valid = False + for include_test in include_list: + pattern = re.compile("^" + include_test) + if pattern.match(test_path) is not None: + is_valid = True + break + + if not is_valid: + return is_valid + + if exclude_list is not None and len(exclude_list) > 0: + is_valid = True + for exclude_test in exclude_list: + pattern = re.compile("^" + exclude_test) + if pattern.match(test_path) is not None: + is_valid = False + break + + return is_valid + + def _load_test_list(self, file_path): + tests = [] + if not os.path.isfile(file_path): + return tests + + file_content = None + with open(file_path) as file_handle: + file_content = file_handle.read() + + for line in file_content.split(): + line = line.replace(" ", "") + line = re.sub(r"^#", "", line) + if line == "": + continue + tests.append(line) + + return tests + + def get_tests( + self, + types=None, + include_list=None, + exclude_list=None, + reference_tokens=None + ): + if types is None: + types = [AUTOMATIC, MANUAL] + if include_list is None: + include_list = [] + if exclude_list is None: + exclude_list = [] + if reference_tokens is None: + reference_tokens = [] + + loaded_tests = {} + + reference_results = self._results_manager.read_common_passed_tests( + reference_tokens) + + for test_type in types: + if test_type not in TEST_TYPES: + continue + for api in self._tests[test_type]: + for test_path in self._tests[test_type][api]: + if not self._is_valid_test(test_path, exclude_list, + include_list): + continue + if reference_results is not None and \ + test_path not in reference_results[api]: + continue + if api not in loaded_tests: + loaded_tests[api] = [] + loaded_tests[api].append(test_path) + return loaded_tests + + def get_apis(self): + apis = [] + for test_type in TEST_TYPES: + for api in self._tests[test_type]: + in_list = False + for item in apis: + if item["path"] == "/" + api: + in_list = True + break + if in_list: + continue + title = None + for item in self._api_titles: + if item["path"] == "/" + api: + title = item["title"] + break + + if title is None: + apis.append({"title": api, "path": "/" + api}) + else: + apis.append({"title": title, "path": "/" + api}) + return apis diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/tests_manager.py b/tests/wpt/web-platform-tests/tools/wave/testing/tests_manager.py new file mode 100644 index 00000000000..aa8b919a9fc --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/tests_manager.py @@ -0,0 +1,369 @@ +from __future__ import division +from __future__ import absolute_import +from __future__ import unicode_literals +import re +from threading import Timer + +from .event_dispatcher import TEST_COMPLETED_EVENT + +from ..data.exceptions.not_found_exception import NotFoundException +from ..data.session import COMPLETED, ABORTED + + +class TestsManager(object): + def initialize( + self, + test_loader, + sessions_manager, + results_manager, + event_dispatcher + ): + self._test_loader = test_loader + self._sessions_manager = sessions_manager + self._results_manager = results_manager + self._event_dispatcher = event_dispatcher + + self._timeouts = [] + + def next_test(self, session): + if session.status == COMPLETED or session.status == ABORTED: + return None + + pending_tests = session.pending_tests + running_tests = session.running_tests + token = session.token + + if pending_tests is None: + pending_tests = self.load_tests(session) + session.pending_tests = pending_tests + self._sessions_manager.update_session(session) + + if running_tests is None: + running_tests = {} + + test = self._get_next_test_from_list(pending_tests) + if test is None: + return None + + pending_tests = self.remove_test_from_list(pending_tests, test) + running_tests = self.add_test_to_list(running_tests, test) + + test_timeout = self.get_test_timeout(test, session) / 1000.0 + + def handler(self, token, test): + self._on_test_timeout(token, test) + + timer = Timer(test_timeout, handler, [self, token, test]) + self._timeouts.append({ + "test": test, + "timeout": timer + }) + + session.pending_tests = pending_tests + session.running_tests = running_tests + self._sessions_manager.update_session(session) + + timer.start() + return test + + def read_last_completed_tests(self, token, count): + results = self._results_manager.read_results(token) + + results_tests = {} + for api in list(results.keys()): + results_tests[api] = [] + for result in results[api]: + results_tests[api].append(result["test"]) + + sorted_results_tests = self._sort_tests_by_execution(results_tests) + sorted_results_tests.reverse() + + tests = {"pass": [], "fail": [], "timeout": []} + + for test in sorted_results_tests: + api = None + for part in test.split("/"): + if part != "": + api = part + break + + result = None + for potential_result in results[api]: + if potential_result["test"] == test: + result = potential_result + break + + if result["status"] == "ERROR": + if len(tests["fail"]) < count: + tests["fail"].append(result["test"]) + elif result["status"] == "TIMEOUT": + if len(tests["timeout"]) < count: + tests["timeout"].append(result["test"]) + passes = True + for test in result["subtests"]: + if test["status"] != "PASS": + passes = False + break + + if passes and len(tests["pass"]) < count: + tests["pass"].append(result["test"]) + if not passes and len(tests["fail"]) < count: + tests["fail"].append(result["test"]) + if len(tests["pass"]) == count and len(tests["fail"]) == count \ + and len(tests["timeout"]) == count: + return tests + return tests + + def _sort_tests_by_execution(self, tests): + sorted_tests = [] + + for api in list(tests.keys()): + for test in tests[api]: + sorted_tests.append(test) + + def compare(tests_manager, test_a, test_b): + micro_test_list = {} + api_a = "" + for part in test_a.split("/"): + if part != "": + api_a = part + break + api_b = "" + for part in test_b.split("/"): + if part != "": + api_b = part + break + if api_a == api_b: + micro_test_list[api_a] = [test_a, test_b] + else: + micro_test_list[api_a] = [test_a] + micro_test_list[api_b] = [test_b] + next_test = tests_manager._get_next_test_from_list(micro_test_list) + if next_test == test_a: + return -1 + return 1 + + sorted_tests.sort(cmp=lambda test_a, + test_b: compare(self, test_a, test_b)) + return sorted_tests + + def _get_next_test_from_list(self, tests): + test = None + api = None + has_http = True + has_manual = True + current_api = 0 + current_test = 0 + + apis = list(tests.keys()) + apis.sort(key=lambda api: api.lower()) + + for api in apis: + tests[api].sort(key=lambda api: api.replace("/", "").lower()) + + while test is None: + if len(apis) <= current_api: + return None + api = apis[current_api] + + if len(tests[api]) <= current_test: + current_api = current_api + 1 + current_test = 0 + + if current_api == len(apis): + if has_http: + has_http = False + current_api = 0 + test = None + continue + + if has_manual: + has_manual = False + current_api = 0 + test = None + has_http = True + continue + + return None + + test = None + continue + test = tests[api][current_test] + + if "manual" in test and "https" not in test: + return test + + if "manual" in test and "https" in test: + if not has_http: + return test + + if "manual" not in test and "https" not in test: + if not has_manual: + return test + + if "manual" not in test and "https" in test: + if not has_manual and not has_http: + return test + + current_test = current_test + 1 + test = None + + return test + + def skip_to(self, test_list, test): + sorted_tests = self._sort_tests_by_execution(test_list) + if test not in sorted_tests: + return test_list + index = sorted_tests.index(test) + remaining_tests = sorted_tests[index + 1:] + remaining_tests_by_api = {} + current_api = "___" + for test in remaining_tests: + if not test.startswith("/" + current_api) and \ + not test.startswith(current_api): + current_api = next((p for p in test.split("/") if p != ""), + None) + if current_api not in remaining_tests_by_api: + remaining_tests_by_api[current_api] = [] + remaining_tests_by_api[current_api].append(test) + return remaining_tests_by_api + + def remove_test_from_list(self, test_list, test): + api = None + for part in test.split("/"): + if part is None or part == "": + continue + api = part + break + if api not in test_list: + return test_list + if test not in test_list[api]: + return test_list + test_list[api].remove(test) + if len(test_list[api]) == 0: + del test_list[api] + + return test_list + + def add_test_to_list(self, test_list, test): + api = None + for part in test.split("/"): + if part is None or part == "": + continue + api = part + break + if api in test_list and test in test_list[api]: + return test_list + if api not in test_list: + test_list[api] = [] + test_list[api].append(test) + return test_list + + def get_test_timeout(self, test, session): + timeouts = session.timeouts + test_timeout = None + + for path in list(timeouts.keys()): + pattern = re.compile("^" + path.replace(".", "")) + if pattern.match(test.replace(".", "")) is not None: + test_timeout = timeouts[path] + break + + if test_timeout is None: + if "manual" in test: + test_timeout = timeouts["manual"] + else: + test_timeout = timeouts["automatic"] + + return test_timeout + + def _on_test_timeout(self, token, test): + data = { + "test": test, + "status": "TIMEOUT", + "message": None, + "subtests": [ + { + "status": "TIMEOUT", + "xstatus": "SERVERTIMEOUT" + } + ] + } + + self._results_manager.create_result(token, data) + + def read_tests(self): + return self._test_loader.get_tests() + + def complete_test(self, test, session): + running_tests = session.running_tests + + running_tests = self.remove_test_from_list(running_tests, test) + session.running_tests = running_tests + + timeout = next((t for t in self._timeouts if t["test"] == test), None) + timeout["timeout"].cancel() + self._timeouts.remove(timeout) + + self.update_tests( + running_tests=running_tests, + session=session + ) + + self._event_dispatcher.dispatch_event( + token=session.token, + event_type=TEST_COMPLETED_EVENT, + data=test + ) + + def update_tests( + self, + pending_tests=None, + running_tests=None, + session=None + ): + if pending_tests is not None: + session.pending_tests = pending_tests + + if running_tests is not None: + session.running_tests = running_tests + + self._sessions_manager.update_session(session) + + def calculate_test_files_count(self, tests): + count = {} + for api in tests: + count[api] = len(tests[api]) + return count + + def read_malfunctioning_tests(self, token): + session = self._sessions_manager.read_session(token) + return session.malfunctioning_tests + + def update_malfunctioning_tests(self, token, tests): + if token is None: + return + if tests is None: + return + + session = self._sessions_manager.read_session(token) + if session is None: + raise NotFoundException("Could not find session using token: " + token) + if session.is_public: + return + session.malfunctioning_tests = tests + self._sessions_manager.update_session(session) + + def load_tests(self, session): + pending_tests = self._test_loader.get_tests( + session.types, + include_list=session.tests["include"], + exclude_list=session.tests["exclude"], + reference_tokens=session.reference_tokens + ) + + last_completed_test = session.last_completed_test + if last_completed_test is not None: + pending_tests = self.skip_to(pending_tests, last_completed_test) + + return pending_tests diff --git a/tests/wpt/web-platform-tests/tools/wave/testing/wpt_report.py b/tests/wpt/web-platform-tests/tools/wave/testing/wpt_report.py new file mode 100644 index 00000000000..e10de774458 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/testing/wpt_report.py @@ -0,0 +1,56 @@ +from __future__ import unicode_literals +import subprocess +import os +import ntpath +import sys +from shutil import copyfile + + +def generate_report( + input_json_directory_path=None, + output_html_directory_path=None, + spec_name=None, + is_multi=None, + reference_dir=None): + if is_multi is None: + is_multi = False + try: + command = [ + "wptreport", + "--input", input_json_directory_path, + "--output", output_html_directory_path, + "--spec", spec_name, + "--sort", "true", + "--failures", "true", + "--tokenFileName", "true" if is_multi else "false", + "--pass", "100", + "--ref", reference_dir if reference_dir is not None else ""] + whole_command = "" + for command_part in command: + whole_command += command_part + " " + subprocess.call(command, shell=False) + except subprocess.CalledProcessError as e: + info = sys.exc_info() + raise Exception("Failed to execute wptreport: " + str(info[0].__name__) + ": " + e.output) + + +def generate_multi_report( + output_html_directory_path=None, + spec_name=None, + result_json_files=None, + reference_dir=None): + for file in result_json_files: + if not os.path.isfile(file["path"]): + continue + file_name = ntpath.basename(file["path"]) + copyfile(file["path"], os.path.join( + output_html_directory_path, + file["token"] + "-" + file_name + )) + + generate_report( + input_json_directory_path=output_html_directory_path, + output_html_directory_path=output_html_directory_path, + spec_name=spec_name, + is_multi=True, + reference_dir=reference_dir) diff --git a/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Local.postman_environment.json b/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Local.postman_environment.json new file mode 100644 index 00000000000..b1a6a089ab5 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Local.postman_environment.json @@ -0,0 +1,34 @@ +{ + "id": "37be8ec4-7855-4554-867e-7a5d2a4f99e6", + "name": "WAVE Local", + "values": [ + { + "key": "host", + "value": "web-platform.test", + "enabled": true + }, + { + "key": "port", + "value": "8000", + "enabled": true + }, + { + "key": "protocol", + "value": "http", + "enabled": true + }, + { + "key": "web_root", + "value": "_wave", + "enabled": true + }, + { + "key": "device_timeout", + "value": "60000", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-05-25T12:12:37.098Z", + "_postman_exported_using": "Postman/7.25.0" +} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Server REST API Tests.postman_collection.json b/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Server REST API Tests.postman_collection.json new file mode 100644 index 00000000000..a0801bb77e3 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/tests/WAVE Server REST API Tests.postman_collection.json @@ -0,0 +1,9183 @@ +{ + "info": { + "_postman_id": "ccd6117a-6d61-4617-a6a1-7115db4d4d92", + "name": "WAVE Server REST API Tests", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Read Available Tests", + "item": [ + { + "name": "Read Available Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "051bef94-5544-4ddb-9d85-167677ebecb2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var availableTests = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(typeof availableTests).to.equal(\"object\");", + " for (var api of Object.keys(availableTests)) {", + " pm.expect(availableTests[api]).to.be.an.instanceof(Array);", + " var apiRegExp = new RegExp(\"^/\" + api, \"i\");", + " for (var test of availableTests[api]) {", + " pm.expect(test).to.match(apiRegExp);", + " }", + " }", + "});", + "", + "var includedTests = [];", + "var excludedTests = [];", + "var specialTimeoutTest = \"\";", + "", + "var apis = Object.keys(availableTests);", + "for(var api of apis) {", + " if (availableTests[api].length > 50) {", + " var subDirs = availableTests[api].map(test => test.split(\"/\").filter(part => !!part).join(\"/\").split(\"/\")[1]).reduce((acc, curr) => acc.indexOf(curr) === -1 ? acc.concat([curr]) : acc, []);", + " if (subDirs.length > 2) {", + " includedTests.push(\"/\" + api);", + " excludedTests.push(\"/\" + api + \"/\" + subDirs[0]);", + " specialTimeoutTest = availableTests[api][availableTests[api].length - 1];", + " break;", + " }", + " ", + " }", + "}", + "", + "pm.globals.set(\"available_tests\", availableTests);", + "pm.globals.set(\"included_tests\", JSON.stringify(includedTests));", + "pm.globals.set(\"excluded_tests\", JSON.stringify(excludedTests));", + "pm.globals.set(\"special_timeout_test\", specialTimeoutTest.replace(\".\", \"\"));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Create and Read Sessions", + "item": [ + { + "name": "Start expiring session remove expiration date", + "item": [ + { + "name": "Create Session With Expiration", + "event": [ + { + "listen": "test", + "script": { + "id": "a8bf3e41-a7df-4c6b-8a20-3a1e6d8a51d9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "4370546f-b08c-4f77-9bd9-1cd14400665e", + "exec": [ + "var expirationDate = Date.now() + 10000;", + "pm.globals.set(\"expiration_date\", expirationDate);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"expiration_date\": {{expiration_date}}\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "3dcb5b6c-9151-49f7-a1a6-74475927b304", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure contains expiration date\", function () {", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + "});", + "", + "var expirationDate = pm.globals.get(\"expiration_date\");", + "", + "pm.test(\"Expiration date is as specified\", function () {", + " pm.expect(Date.parse(jsonData.expiration_date)).to.equal(expirationDate);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "8d05578a-e2d6-41e9-a2a4-aa7d92bfbbce", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "4c5e3ba4-e27b-4341-8cf8-74ed047a8747", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure contains expiration date\", function () {", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + "});", + "", + "pm.test(\"Expiration date is null\", function () {", + " pm.expect(jsonData.expiration_date).to.be.null;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Read Public Sessions", + "item": [ + { + "name": "Read Public Sessions", + "event": [ + { + "listen": "test", + "script": { + "id": "1081afd8-a772-4565-b03d-b58f773cbb65", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Response is JSON Array\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an.instanceof(Array);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/public", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "public" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Find Session", + "item": [ + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "268e8a31-87bb-4ec5-81d5-87dc74096828", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Find Session Token", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "625fcc2a-f7b1-403c-b5c5-56db7c5bcee5", + "exec": [ + "const token = pm.globals.get(\"session_token\");", + "pm.globals.set(\"session_token_fragment\", token.split(\"-\").shift());" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "8e04212f-e259-413f-98ee-e366cd3adfdd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const sessionToken = pm.globals.get(\"session_token\");", + "", + "pm.test(\"Found token is original token\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.token).to.equal(sessionToken);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token_fragment}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token_fragment}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Find Session Too Short Fragment", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "6f8429e3-9c12-423c-baaf-8f8de0e4ea49", + "exec": [ + "const token = pm.globals.get(\"session_token\");", + "pm.globals.set(\"session_token_fragment\", token.split(\"-\").shift());" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "7f6ef567-274e-4f9d-b7fc-50f8240547e9", + "exec": [ + "pm.test(\"Status code is 404\", function () {", + " pm.response.to.have.status(404);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/1234567", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "1234567" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Read Next Test", + "item": [ + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Invalid Session", + "event": [ + { + "listen": "test", + "script": { + "id": "11f5c620-dc3b-4a8c-8d2f-f9663025c79f", + "exec": [ + "pm.test(\"Status code is 404\", function () {", + " pm.response.to.have.status(404);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Create Session \\w Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "c67cde7e-7237-479c-a0c6-b84a533c3b1e", + "exec": [ + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "24b38d64-5c24-415f-b6f6-f8d252d69ac8", + "exec": [ + "var automaticTimeout = 120000;", + "var manualTimeout = 1000000;", + "var specialTimeout = 2000;", + "", + "pm.globals.set(\"automatic_timeout\", automaticTimeout);", + "pm.globals.set(\"manual_timeout\", manualTimeout);", + "pm.globals.set(\"special_timeout\", specialTimeout);", + "", + "const availableTests = pm.globals.get(\"available_tests\");", + "const test1 = availableTests[Object.keys(availableTests)[0]][0];", + "", + "pm.globals.set(\"single_test_1\", test1);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": [\"{{single_test_1}}\"]\n },\n \"types\": [\n \"automatic\"\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Pending Session", + "event": [ + { + "listen": "test", + "script": { + "id": "0806e4e0-bd1b-40ba-a7d5-74d41473a141", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const nextTest = jsonData.next_test;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "", + "const web_root = pm.environment.get(\"web_root\");", + "", + "pm.test(\"Returned test is new session page\", function () {", + " pm.expect(test).to.equal(\"/\" + web_root + \"/newsession.html\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "9b1f2dec-9949-49ff-b466-f602b11dde5d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Running Session", + "event": [ + { + "listen": "test", + "script": { + "id": "7fea2977-5ccb-49ee-8f07-79a7f2245f9c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const nextTest = jsonData.next_test;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "const api = test.split(\"/\").filter(part => !!part)[0]", + "const availableTests = pm.globals.get(\"available_tests\")", + "", + "pm.test(\"Returned test is valid test\", function () {", + " pm.expect(availableTests).to.have.property(api);", + " pm.expect(availableTests[api]).to.contain(test)", + "});", + "", + "", + "setTimeout(function () {}, 1000);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "event": [ + { + "listen": "test", + "script": { + "id": "7cc27ee8-2f06-4e25-98fb-9872c6cf0d93", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"FAIL\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Completed Session", + "event": [ + { + "listen": "test", + "script": { + "id": "0a73a5eb-3edb-4d15-924d-260dd22bd831", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const nextTest = jsonData.next_test;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "", + "const web_root = pm.environment.get(\"web_root\");", + "", + "pm.test(\"Returned test is new session page\", function () {", + " pm.expect(test).to.equal(\"/\" + web_root + \"/finish.html\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Session \\w Configuration Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "94877ec6-70ea-4c78-acb5-20060a535653", + "exec": [ + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "dcc29092-b7a1-40fc-8359-ecc655dba482", + "exec": [ + "var automaticTimeout = 120000;", + "var manualTimeout = 1000000;", + "var specialTimeout = 2000;", + "", + "pm.globals.set(\"automatic_timeout\", automaticTimeout);", + "pm.globals.set(\"manual_timeout\", manualTimeout);", + "pm.globals.set(\"special_timeout\", specialTimeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": {{included_tests}},\n \"exclude\": {{excluded_tests}}\n },\n \"types\": [\n \"automatic\"\n ],\n \"timeouts\": {\n \"automatic\": 1000\n },\n \"labels\": [\"label1\", \"label2\"]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "8f6e2bf2-6c1e-434e-83c5-9bcc57880692", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "a0a80c05-a2ca-430a-8bed-46ad7978c684", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Aborted Session", + "event": [ + { + "listen": "test", + "script": { + "id": "00d823e0-2059-4cab-81d6-8d1de9e5b62a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const nextTest = jsonData.next_test;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "", + "const web_root = pm.environment.get(\"web_root\");", + "", + "pm.test(\"Returned test is new session page\", function () {", + " pm.expect(test).to.equal(\"/\" + web_root + \"/pause.html\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "b8211c13-667d-4970-aedc-6398c25cc40c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Aborted Session", + "event": [ + { + "listen": "test", + "script": { + "id": "8aad813d-53fe-49fd-bdfc-f16ce2233ae2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const nextTest = jsonData.next_test;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "", + "const web_root = pm.environment.get(\"web_root\");", + "", + "pm.test(\"Returned test is new session page\", function () {", + " pm.expect(test).to.equal(\"/\" + web_root + \"/finish.html\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Control Session", + "item": [ + { + "name": "Setup", + "item": [ + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "305cb915-8496-4577-b17a-e8189d66c3d1", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Pause Pending Session", + "item": [ + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "9d903165-9667-43b0-b210-a950d0fa1fa2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "0307919b-6630-48ff-ac18-10c0a47ea254", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is pending\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"pending\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Start Pending Session", + "item": [ + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "f66408d5-5438-4d4f-9bfc-6d24b15e5a90", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "bae5542d-446b-4064-88ff-cc355a8f4f62", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "pm.test(\"Status is running\", function () {", + " pm.expect(jsonData.status).to.equal(\"running\");", + "});", + "", + "pm.test(\"Start date is set\", function () {", + " pm.expect(Date.parse(jsonData.date_started)).to.be.below(Date.now());", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Start Running Session", + "item": [ + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "3b386952-8a37-471a-9192-f28974d975a3", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "8e56d842-325b-4356-ae1a-2465e9efe188", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is running\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"running\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Pause Running Session", + "item": [ + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "a183cb0b-31f0-48f6-9c20-605a16488d7d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "f2610594-813a-4079-afae-1510486efab4", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is paused\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"paused\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Pause Paused Session", + "item": [ + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "6b8ec98a-ad91-4d5c-aa07-6b3cc1255902", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "91a38eb8-a501-457f-a9f4-b63221c957f6", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is paused\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"paused\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Start Paused Session", + "item": [ + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "6e3a8c64-04cb-4c4f-b23d-64655f6e4d22", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "dcf7f6f4-6eef-4a90-a63d-df70446eb209", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is running\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"running\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Stop Running Session", + "item": [ + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "bee7a70d-af1f-4ad1-9c40-7abdbcc983ae", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "217ed267-1ddb-496a-a7c5-6e29bad97c60", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "pm.test(\"Status is aborted\", function () {", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});", + "", + "pm.test(\"Finish date is set\", function () {", + " pm.expect(Date.parse(jsonData.date_finished)).to.be.below(Date.now());", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Stop Aborted Session", + "item": [ + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "a255ea61-5c5a-4f0d-8a67-c244510a608c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "9cc7599b-d378-4b04-bada-9d76f6ca610f", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is aborted\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "81e44e3f-5d91-42a7-b0ab-4704eb121868", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "a44180cb-3b13-421b-b146-82901f2b45bd", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Start Aborted Session", + "item": [ + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "47fb1fa9-4849-4ea9-b36e-fcec8decf62e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "1923ced4-4361-4a4a-bf7c-4fcdf3df50f6", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is aborted\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "226043e5-1a81-4d36-aa7f-67b10bf407af", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "840bf970-0984-452e-9076-b6f66d0b4511", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Pause Aborted Session", + "item": [ + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "88c4072f-538b-4d68-9d61-f0fb017e544c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "2ae00eb3-49e8-4487-b27f-e7c7955fe4f4", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is aborted\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "70e0c783-c405-481c-b9c8-5c8bee392f97", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "85c45e3b-fae6-4a90-afd0-97678769e32c", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Setup", + "item": [ + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "df4a00d1-d4f8-4b0b-892d-21528165a2cf", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "4fa59617-c922-4826-abc6-6d910e918ea4", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "d83f449d-4a2e-41c8-b2cd-5cf0cd1c404e", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Stop Pending Session", + "item": [ + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "98da2b86-4f9f-47dd-afc9-22ce96e73e84", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "6d8a8202-c85d-4ada-b443-45108a372aea", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is aborted\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Setup", + "item": [ + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "0f9df486-91cd-46fc-a711-5cf9bebb2706", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "80ee91fd-98ca-4b8e-83b6-32bf3e55a295", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "47f4d26a-84c2-4980-984d-dac0e95503e1", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "6bd9e85f-eb73-47be-83b0-01be77868899", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "43ebfadb-dc68-4c41-b34e-462e427dc2ef", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Stop Paused Session Copy", + "item": [ + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "029ec84b-e41b-4744-8745-58c50e52bb11", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "071d757c-41aa-4b52-9ab4-6c2afd6ed2af", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is aborted\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"aborted\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "305720a0-2c84-43d3-8fe5-55f8fdf511d8", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "84e4ab04-5acc-4428-a81a-c0b0c53b5fd9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Setup", + "item": [ + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Session One Test", + "event": [ + { + "listen": "test", + "script": { + "id": "b7a9d459-9b39-40b2-abdc-fd8fe8b21d61", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "fcbfb0e3-a10d-4ff8-afed-f5f3c9d52090", + "exec": [ + "const availableTests = pm.globals.get(\"available_tests\");", + "const test = availableTests[Object.keys(availableTests)[0]][0]", + "", + "pm.globals.set(\"single_test\", test);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": [\"{{single_test}}\"]\n }\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "937ef61d-d6d6-4e24-bc3a-696a23cc95d6", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "29f0554b-66f5-4e26-80ff-39b3faba920a", + "exec": [ + "const response = pm.response.json();", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"FAIL\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "9bf66427-6f39-4f0a-b065-1849d679eee6", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "8d1f3837-1f05-47e4-897c-b7c74da9bd43", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Start Completed Session", + "item": [ + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "9bf0fb70-24a0-4136-99fe-8e0e488afd1e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "7e3184bf-1741-44c8-8cd3-cff30c2deca1", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is completed\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"completed\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Pause Completed Session", + "item": [ + { + "name": "Pause Session", + "event": [ + { + "listen": "test", + "script": { + "id": "e323c6af-d4e5-4a05-b203-09ba67f77d28", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/pause", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "pause" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "40cd04ce-850f-4903-bc24-2e62a4df98fe", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is completed\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"completed\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Stop Completed Session", + "item": [ + { + "name": "Stop Session", + "event": [ + { + "listen": "test", + "script": { + "id": "db7d5209-37b2-46bd-88ab-ce4e241401b2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/stop", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "stop" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "477dc63d-0b43-4226-b86e-163e2de92b67", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Status is completed\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.status).to.equal(\"completed\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Clean Up", + "item": [ + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Update and Read Sessions", + "item": [ + { + "name": "Create Default", + "item": [ + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "b923d95e-a7b4-49d4-ab2a-1f435c454387", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "81f36759-7ae2-42b9-81d2-79f57046b46e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"tests\");", + " pm.expect(typeof jsonData.tests).to.equal(\"object\");", + " pm.expect(jsonData.tests).to.have.property(\"include\");", + " pm.expect(jsonData.tests.include).to.be.an.instanceof(Array);", + " pm.expect(jsonData.tests).to.have.property(\"exclude\");", + " pm.expect(jsonData.tests.exclude).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"types\");", + " pm.expect(jsonData.types).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"user_agent\");", + " pm.expect(typeof jsonData.user_agent).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"timeouts\");", + " pm.expect(typeof jsonData.timeouts).to.equal(\"object\")", + " pm.expect(jsonData.timeouts).to.have.property(\"automatic\");", + " pm.expect(typeof jsonData.timeouts.automatic).to.equal(\"number\");", + " pm.expect(jsonData.timeouts).to.have.property(\"manual\");", + " pm.expect(typeof jsonData.timeouts.manual).to.equal(\"number\");", + " pm.expect(jsonData).to.have.property(\"browser\");", + " pm.expect(typeof jsonData.browser).to.equal(\"object\");", + " pm.expect(jsonData.browser).to.have.property(\"name\");", + " pm.expect(typeof jsonData.browser.name).to.equal(\"string\");", + " pm.expect(jsonData.browser).to.have.property(\"version\");", + " pm.expect(typeof jsonData.browser.version).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"reference_tokens\");", + " pm.expect(jsonData.reference_tokens).to.be.an.instanceof(Array);", + "});", + "", + "pm.test(\"Configuration is default\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " pm.expect(jsonData.tests.include).to.include(\"/\");", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(60000);", + " pm.expect(jsonData.timeouts.manual).to.equal(300000);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "2873d554-9816-41f0-9051-fb2cb1272a76", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"status\");", + " pm.expect(typeof jsonData.status).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + " pm.expect(jsonData.expiration_date).to.be.null;", + " pm.expect(jsonData).to.have.property(\"date_started\");", + " pm.expect(jsonData.date_started).to.satisfy(value => !value || typeof value === \"number\");", + " pm.expect(jsonData).to.have.property(\"date_finished\");", + " pm.expect(jsonData.date_finished).to.satisfy(value => !value || typeof value === \"number\");", + "});", + "", + "pm.test(\"Session status is pending\", function () {", + " pm.expect(jsonData.status).to.equal(\"pending\");", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "53605764-d4f0-4b32-9a30-67e84dd104d9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "pm.test(\"All tests are pending tests\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.not.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})", + "", + "const availableTests = pm.globals.get(\"available_tests\"); ", + "", + "pm.test(\"All available tests are part of the session\", function () {", + " for (var api of Object.keys(jsonData.pending_tests)) {", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(availableTests[api]).to.include(test);", + " }", + " }", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "cf165ae9-1c44-483c-8fe4-bd7cdaa20710", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "6938d456-afd5-431b-a95f-a2c45a3ac479", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Update With Configuration", + "item": [ + { + "name": "Update Session", + "event": [ + { + "listen": "test", + "script": { + "id": "657be5b3-4a99-4415-a1ef-9dfdcf541e46", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "093a0019-a84c-44fc-b890-36369d51b7d5", + "exec": [ + "var automaticTimeout = 120000;", + "var manualTimeout = 1000000;", + "var specialTimeout = 2000;", + "", + "pm.globals.set(\"automatic_timeout\", automaticTimeout);", + "pm.globals.set(\"manual_timeout\", manualTimeout);", + "pm.globals.set(\"special_timeout\", specialTimeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": {{included_tests}},\n \"exclude\": {{excluded_tests}}\n },\n \"types\": [\n \"automatic\"\n ],\n \"timeouts\": {\n \"automatic\": {{automatic_timeout}},\n \"manual\": {{manual_timeout}},\n \"{{special_timeout_test}}\": {{special_timeout}}\n }\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "4ac55601-9bdf-41f8-9d59-ff1ee20fa471", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"tests\");", + " pm.expect(typeof jsonData.tests).to.equal(\"object\");", + " pm.expect(jsonData.tests).to.have.property(\"include\");", + " pm.expect(jsonData.tests.include).to.be.an.instanceof(Array);", + " pm.expect(jsonData.tests).to.have.property(\"exclude\");", + " pm.expect(jsonData.tests.exclude).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"types\");", + " pm.expect(jsonData.types).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"user_agent\");", + " pm.expect(typeof jsonData.user_agent).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"timeouts\");", + " pm.expect(typeof jsonData.timeouts).to.equal(\"object\")", + " pm.expect(jsonData.timeouts).to.have.property(\"automatic\");", + " pm.expect(typeof jsonData.timeouts.automatic).to.equal(\"number\");", + " pm.expect(jsonData.timeouts).to.have.property(\"manual\");", + " pm.expect(typeof jsonData.timeouts.manual).to.equal(\"number\");", + " pm.expect(jsonData).to.have.property(\"browser\");", + " pm.expect(typeof jsonData.browser).to.equal(\"object\");", + " pm.expect(jsonData.browser).to.have.property(\"name\");", + " pm.expect(typeof jsonData.browser.name).to.equal(\"string\");", + " pm.expect(jsonData.browser).to.have.property(\"version\");", + " pm.expect(typeof jsonData.browser.version).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"reference_tokens\");", + " pm.expect(jsonData.reference_tokens).to.be.an.instanceof(Array);", + "});", + "", + "var includedTests = JSON.parse(pm.globals.get(\"included_tests\"));", + "var excludedTests = JSON.parse(pm.globals.get(\"excluded_tests\"));", + "var automaticTimeout = pm.globals.get(\"automatic_timeout\");", + "var manualTimeout = pm.globals.get(\"manual_timeout\");", + "var specialTimeout = pm.globals.get(\"special_timeout\");", + "var specialTimeoutTest = pm.globals.get(\"special_timeout_test\");", + "", + "pm.test(\"Configuration is as specified\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " for (var test of includedTests) {", + " pm.expect(jsonData.tests.include).to.include(test);", + " }", + " for (var test of excludedTests) {", + " pm.expect(jsonData.tests.exclude).to.include(test);", + " }", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.not.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(automaticTimeout);", + " pm.expect(jsonData.timeouts.manual).to.equal(manualTimeout);", + " pm.expect(jsonData.timeouts[specialTimeoutTest]).to.equal(specialTimeout);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "0b49c01b-e943-4879-b441-4093836d05e9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "pm.test(\"All tests are pending tests\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.not.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})", + "", + "const availableTests = pm.globals.get(\"available_tests\");", + "const includedTests = pm.globals.get(\"included_tests\");", + "const excludedTests = pm.globals.get(\"excluded_tests\");", + "", + "pm.test(\"Selected subset of tests are part of the session\", function () {", + " for (var api of Object.keys(jsonData.pending_tests)) {", + " for (var includedTest of includedTests) {", + " if (includedTest.split(\"/\").find(part => !!part) === api) {", + " var includeRegExp = new RegExp(\"^\" + includedTest, \"i\");", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(test).to.match(regex);", + " }", + " break;", + " }", + " }", + " for (var excludedTest of excludedTests) {", + " if (excludedTest.split(\"/\").find(part => !!part) === api) {", + " var excludeRegExp = new RegExp(\"^\" + excludedTest, \"i\");", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(test).to.not.match(regex);", + " }", + " break;", + " }", + " }", + " }", + "});", + "", + "const sessionTests = jsonData.pending_tests;", + "", + "pm.globals.set(\"session_tests\", JSON.stringify(sessionTests));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "b9cba19f-88d2-41f6-940a-a0979da05500", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"status\");", + " pm.expect(typeof jsonData.status).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + " pm.expect(jsonData.expiration_date).to.be.null;", + " pm.expect(jsonData).to.have.property(\"date_started\");", + " pm.expect(jsonData.date_started).to.satisfy(value => !value || typeof value === \"number\");", + " pm.expect(jsonData).to.have.property(\"date_finished\");", + " pm.expect(jsonData.date_finished).to.satisfy(value => !value || typeof value === \"number\");", + "});", + "", + "pm.test(\"Session status is pending\", function () {", + " pm.expect(jsonData.status).to.equal(\"pending\");", + "})", + "", + "pm.test(\"Start and Finish date not set\", function () {", + " pm.expect(jsonData.date_started).to.be.null;", + " pm.expect(jsonData.date_finished).to.be.null;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "3669c70a-88bc-4854-abac-5cb80a21c392", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "1a81f5c5-28d8-4935-b8ae-822e33c23da9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Update Session Labels", + "item": [ + { + "name": "Create Session \\w Configuration Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "9de9321c-ae78-4abd-a740-6634e2cbb9b9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "739284e7-17ac-4c34-baa1-933353eb7ecc", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"labels\": [\"label1\", \"label2\"]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "5b15f338-c773-4f48-8f78-1d7c926beb81", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"tests\");", + " pm.expect(typeof jsonData.tests).to.equal(\"object\");", + " pm.expect(jsonData.tests).to.have.property(\"include\");", + " pm.expect(jsonData.tests.include).to.be.an.instanceof(Array);", + " pm.expect(jsonData.tests).to.have.property(\"exclude\");", + " pm.expect(jsonData.tests.exclude).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"types\");", + " pm.expect(jsonData.types).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"user_agent\");", + " pm.expect(typeof jsonData.user_agent).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"timeouts\");", + " pm.expect(typeof jsonData.timeouts).to.equal(\"object\")", + " pm.expect(jsonData.timeouts).to.have.property(\"automatic\");", + " pm.expect(typeof jsonData.timeouts.automatic).to.equal(\"number\");", + " pm.expect(jsonData.timeouts).to.have.property(\"manual\");", + " pm.expect(typeof jsonData.timeouts.manual).to.equal(\"number\");", + " pm.expect(jsonData).to.have.property(\"browser\");", + " pm.expect(typeof jsonData.browser).to.equal(\"object\");", + " pm.expect(jsonData.browser).to.have.property(\"name\");", + " pm.expect(typeof jsonData.browser.name).to.equal(\"string\");", + " pm.expect(jsonData.browser).to.have.property(\"version\");", + " pm.expect(typeof jsonData.browser.version).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"reference_tokens\");", + " pm.expect(jsonData.reference_tokens).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"labels\");", + " pm.expect(jsonData.labels).to.be.an.instanceof(Array);", + "});", + "", + "pm.test(\"Configuration is default\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " pm.expect(jsonData.tests.include).to.include(\"/\");", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(60000);", + " pm.expect(jsonData.timeouts.manual).to.equal(300000);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + " pm.expect(jsonData.labels).to.include(\"label1\");", + " pm.expect(jsonData.labels).to.include(\"label2\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Update Labels Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "e69b7188-b3c9-4f66-8c6c-3f3348f84f6a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"labels\": [\"new\", \"labels\"]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/labels", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "labels" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "86e20c4d-5797-4b6e-a8cc-14e284e7c491", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"tests\");", + " pm.expect(typeof jsonData.tests).to.equal(\"object\");", + " pm.expect(jsonData.tests).to.have.property(\"include\");", + " pm.expect(jsonData.tests.include).to.be.an.instanceof(Array);", + " pm.expect(jsonData.tests).to.have.property(\"exclude\");", + " pm.expect(jsonData.tests.exclude).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"types\");", + " pm.expect(jsonData.types).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"user_agent\");", + " pm.expect(typeof jsonData.user_agent).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"timeouts\");", + " pm.expect(typeof jsonData.timeouts).to.equal(\"object\")", + " pm.expect(jsonData.timeouts).to.have.property(\"automatic\");", + " pm.expect(typeof jsonData.timeouts.automatic).to.equal(\"number\");", + " pm.expect(jsonData.timeouts).to.have.property(\"manual\");", + " pm.expect(typeof jsonData.timeouts.manual).to.equal(\"number\");", + " pm.expect(jsonData).to.have.property(\"browser\");", + " pm.expect(typeof jsonData.browser).to.equal(\"object\");", + " pm.expect(jsonData.browser).to.have.property(\"name\");", + " pm.expect(typeof jsonData.browser.name).to.equal(\"string\");", + " pm.expect(jsonData.browser).to.have.property(\"version\");", + " pm.expect(typeof jsonData.browser.version).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"reference_tokens\");", + " pm.expect(jsonData.reference_tokens).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"labels\");", + " pm.expect(jsonData.labels).to.be.an.instanceof(Array);", + "});", + "", + "pm.test(\"Configuration is default\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " pm.expect(jsonData.tests.include).to.include(\"/\");", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(60000);", + " pm.expect(jsonData.timeouts.manual).to.equal(300000);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + " pm.expect(jsonData.labels).to.include(\"new\");", + " pm.expect(jsonData.labels).to.include(\"labels\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean Up", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Delete Session", + "item": [ + { + "name": "Setup", + "item": [ + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "e85fd539-4598-47a9-8768-656656f29fec", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Delete Session", + "event": [ + { + "listen": "test", + "script": { + "id": "8e9fe4af-0d50-49eb-8a4a-00e13021b4a6", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "9418112a-03f6-4641-893e-076c8922c0af", + "exec": [ + "pm.test(\"Status code is 404\", function () {", + " pm.response.to.have.status(404);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Create and Read Results", + "item": [ + { + "name": "Create Session", + "item": [ + { + "name": "Create Session Two Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "a6995ff1-d626-4f4f-a1e0-567f3429bf52", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "85c7ad8d-5fc9-403d-8715-c65d5ff1323e", + "exec": [ + "const availableTests = pm.globals.get(\"available_tests\");", + "const test1 = availableTests[Object.keys(availableTests)[0]][0];", + "const test2 = availableTests[Object.keys(availableTests)[1]][0];", + "", + "pm.globals.set(\"single_test_1\", test1);", + "pm.globals.set(\"single_test_2\", test2);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": [\"{{single_test_1}}\", \"{{single_test_2}}\"]\n }\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "35cf4745-0301-4c9c-b6b3-40945299533f", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Results", + "event": [ + { + "listen": "test", + "script": { + "id": "6dc082ef-80ff-407a-a562-e25e37476eee", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Responds with no results\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(typeof jsonData).to.equal(\"object\");", + " pm.expect(Object.keys(jsonData)).to.be.empty;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ], + "query": [ + { + "key": "path", + "value": "/2dcontext/drawing-images-to-the-canvas", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements/2d.missingargs.html", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Read Results Compact", + "event": [ + { + "listen": "test", + "script": { + "id": "fcade663-dbd8-42c9-8344-53ae1feb6fcb", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var singleTest1 = pm.globals.get(\"single_test_1\");", + "var singleTest2 = pm.globals.get(\"single_test_2\");", + "", + "var api1 = singleTest1.split(\"/\").find(part => !!part);", + "var api2 = singleTest2.split(\"/\").find(part => !!part);", + "", + "pm.test(\"Responds with no results\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(typeof jsonData).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(api1);", + " pm.expect(jsonData).to.have.property(api2);", + " pm.expect(jsonData[api1].complete).to.equal(0);", + " pm.expect(jsonData[api2].complete).to.equal(0);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/compact", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "compact" + ] + } + }, + "response": [] + }, + { + "name": "Read Last Completed Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "36d70d08-3caa-4312-9bbd-aed15fd238dd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + " ", + "pm.test(\"JSON format is as expected\", function () {", + " pm.expect(Object.keys(jsonData)).to.have.lengthOf(3);", + " pm.expect(jsonData).to.have.property(\"pass\");", + " pm.expect(jsonData).to.have.property(\"fail\");", + " pm.expect(jsonData).to.have.property(\"timeout\");", + " for (var key of Object.keys(jsonData)) {", + " pm.expect(jsonData[key]).to.be.an.instanceof(Array);", + " }", + "});", + "", + "pm.test(\"Responds with no last completed tests\", function () {", + " for (var key of Object.keys(jsonData)) {", + " pm.expect(jsonData[key]).to.be.empty;", + " }", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/last_completed", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "last_completed" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "211adcf7-d71a-4b0f-94ab-d285fc8367df", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "const sessionTests = jsonData.pending_tests;", + "", + "pm.globals.set(\"session_tests\", JSON.stringify(sessionTests));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Create First Result", + "item": [ + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "5410c9c2-ebbe-4bc1-ac12-e2602d8ade57", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(Object.keys(response)).to.have.lengthOf(1);", + " pm.expect(response).to.have.property(\"next_test\");", + " pm.expect(typeof response.next_test).to.equal(\"string\");", + "});", + "", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "", + "pm.test(\"Returned test is first of two specified tests\", function () {", + " pm.expect(test).to.equal(test1);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "e4f9a03f-c731-4192-a9a9-aa9e315c3c44", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"One test is pending, one test is running\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.have.lengthOf(1);", + " var api = Object.keys(jsonData.pending_tests)[0];", + " pm.expect(jsonData.pending_tests[api]).to.have.lengthOf(1);", + " pm.expect(jsonData.pending_tests[api]).to.include(test2);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(1);", + " api = Object.keys(jsonData.running_tests)[0];", + " pm.expect(jsonData.running_tests[api]).to.have.lengthOf(1);", + " pm.expect(jsonData.running_tests[api]).to.include(test1);", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "event": [ + { + "listen": "test", + "script": { + "id": "9f684f77-4ed0-4cd2-99a4-b1c134432e9f", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"FAIL\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "33601dd0-6786-4c8a-a6b5-7f1386129de7", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"One test is pending, one test is completed\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.have.lengthOf(1);", + " var api = Object.keys(jsonData.pending_tests)[0];", + " pm.expect(jsonData.pending_tests[api]).to.have.lengthOf(1);", + " pm.expect(jsonData.pending_tests[api]).to.include(test2);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "97be92f1-a8d1-41ea-b41d-0ca08113e6e1", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"status\");", + " pm.expect(typeof jsonData.status).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + " pm.expect(jsonData.expiration_date).to.be.null;", + " pm.expect(jsonData).to.have.property(\"date_started\");", + " pm.expect(jsonData).to.have.property(\"date_finished\");", + "});", + "", + "pm.test(\"Session status is running\", function () {", + " pm.expect(jsonData.status).to.equal(\"running\");", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Read Last Completed Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "24ec2b79-c266-473f-8579-7b694079d640", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + " ", + "pm.test(\"JSON format is as expected\", function () {", + " pm.expect(Object.keys(jsonData)).to.have.lengthOf(3);", + " pm.expect(jsonData).to.have.property(\"pass\");", + " pm.expect(jsonData).to.have.property(\"fail\");", + " pm.expect(jsonData).to.have.property(\"timeout\");", + " for (var key of Object.keys(jsonData)) {", + " pm.expect(jsonData[key]).to.be.an.instanceof(Array);", + " }", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "", + "pm.test(\"Responds with one last completed tests as failed\", function () {", + " pm.expect(jsonData[\"pass\"]).to.be.empty;", + " pm.expect(jsonData[\"fail\"]).to.have.lengthOf(1);", + " pm.expect(jsonData[\"fail\"][0]).to.equal(test1);", + " pm.expect(jsonData[\"timeout\"]).to.be.empty;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/last_completed", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "last_completed" + ] + } + }, + "response": [] + }, + { + "name": "Read Results", + "event": [ + { + "listen": "test", + "script": { + "id": "1f47b39f-727f-43b4-934d-c7f62b268baa", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON format is as expected\", function () {", + " for (var api of Object.keys(jsonData)) {", + " pm.expect(jsonData[api]).to.be.an.instanceof(Array);", + " for (var result of jsonData[api]) {", + " pm.expect(typeof result).to.equal(\"object\");", + " pm.expect(Object.keys(result)).to.have.lengthOf(4);", + " pm.expect(result).to.have.property(\"test\");", + " pm.expect(typeof result.test).to.equal(\"string\");", + " pm.expect(result).to.have.property(\"status\");", + " pm.expect(typeof result.status).to.equal(\"string\");", + " pm.expect(result).to.have.property(\"message\");", + " pm.expect(result.message).to.satisfy(message => !message || typeof message === \"string\");", + " pm.expect(result).to.have.property(\"subtests\");", + " pm.expect(result.subtests).to.be.an.instanceof(Array);", + " for (var subtest of result.subtests) {", + " pm.expect(typeof subtest).to.equal(\"object\");", + " pm.expect(Object.keys(subtest)).to.have.lengthOf(3);", + " pm.expect(subtest).to.have.property(\"name\");", + " pm.expect(typeof subtest.name).to.equal(\"string\");", + " pm.expect(subtest).to.have.property(\"status\");", + " pm.expect(typeof subtest.status).to.equal(\"string\");", + " pm.expect(subtest).to.have.property(\"message\");", + " pm.expect(subtest.message).to.satisfy(message => !message || typeof message === \"string\");", + " }", + " }", + " }", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "", + "pm.test(\"Test is first test, successful run and failed\", function () {", + " var api = Object.keys(jsonData)[0];", + " pm.expect(api).to.equal(test1.split(\"/\").find(part => !!part))", + " var result = jsonData[api][0];", + " pm.expect(result.test).to.equal(test1);", + " pm.expect(result.status).to.equal(\"OK\");", + " pm.expect(result.message).to.be.null;", + " var subtest = result.subtests[0];", + " pm.expect(subtest.status).to.equal(\"FAIL\");", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ], + "query": [ + { + "key": "path", + "value": "/2dcontext/drawing-images-to-the-canvas", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements/2d.missingargs.html", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Read Results Compact", + "event": [ + { + "listen": "test", + "script": { + "id": "e734f074-a0c2-4e54-b427-2827fa732843", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(typeof jsonData).to.equal(\"object\");", + " for (var api of Object.keys(jsonData)) {", + " pm.expect(jsonData[api]).to.have.property(\"pass\");", + " pm.expect(typeof jsonData[api].pass).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"fail\");", + " pm.expect(typeof jsonData[api].fail).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"timeout\");", + " pm.expect(typeof jsonData[api].timeout).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"not_run\");", + " pm.expect(typeof jsonData[api].not_run).to.equal(\"number\");", + " }", + "})", + "", + "pm.test(\"Responds with one test failed\", function () {", + " var api = Object.keys(jsonData)[0];", + " pm.expect(jsonData[api].pass).to.equal(0);", + " pm.expect(jsonData[api].fail).to.equal(1);", + " pm.expect(jsonData[api].timeout).to.equal(0);", + " pm.expect(jsonData[api].not_run).to.equal(0);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/compact", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "compact" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Create Last Result", + "item": [ + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "fd2c11ee-5eca-43f3-89a7-133602c8034a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(Object.keys(response)).to.have.lengthOf(1);", + " pm.expect(response).to.have.property(\"next_test\");", + " pm.expect(typeof response.next_test).to.equal(\"string\");", + "});", + "", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);", + "", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"Returned test is second of two specified tests\", function () {", + " pm.expect(test).to.equal(test2);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "112ee3d5-d4e0-4838-879e-f74c38d0218c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"One test is running\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(1);", + " var api = Object.keys(jsonData.running_tests)[0];", + " pm.expect(jsonData.running_tests[api]).to.have.lengthOf(1);", + " pm.expect(jsonData.running_tests[api]).to.include(test2);", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "event": [ + { + "listen": "test", + "script": { + "id": "79a84ed9-bb07-493d-ab34-8e7693b3ebbd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"PASS\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "c1829043-18dd-4cc1-8091-41981349f4e3", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"status\");", + " pm.expect(typeof jsonData.status).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + " pm.expect(jsonData.expiration_date).to.be.null;", + " pm.expect(jsonData).to.have.property(\"date_started\");", + " pm.expect(jsonData).to.have.property(\"date_finished\");", + "});", + "", + "pm.test(\"Session status is completed\", function () {", + " pm.expect(jsonData.status).to.equal(\"completed\");", + "})", + "", + "pm.test(\"Finish date is set\", function () {", + " pm.expect(Date.parse(jsonData.date_finished)).to.be.below(Date.now());", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "59fee9df-9945-4fdf-a102-9c1b92d915c1", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "var test1Api = test1.split(\"/\").find(part => !!part);", + "var test2Api = test1.split(\"/\").find(part => !!part);", + "", + "pm.test(\"One test is pending, one test is completed\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Last Completed Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "91fa38ac-3b06-488a-892e-59458e88a4da", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + " ", + "pm.test(\"JSON format is as expected\", function () {", + " pm.expect(Object.keys(jsonData)).to.have.lengthOf(3);", + " pm.expect(jsonData).to.have.property(\"pass\");", + " pm.expect(jsonData).to.have.property(\"fail\");", + " pm.expect(jsonData).to.have.property(\"timeout\");", + " for (var key of Object.keys(jsonData)) {", + " pm.expect(jsonData[key]).to.be.an.instanceof(Array);", + " }", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"Responds with one last completed tests as failed and one last completed test as passed\", function () {", + " pm.expect(jsonData[\"pass\"]).to.have.lengthOf(1);", + " pm.expect(jsonData[\"pass\"][0]).to.equal(test2);", + " pm.expect(jsonData[\"fail\"]).to.have.lengthOf(1);", + " pm.expect(jsonData[\"fail\"][0]).to.equal(test1);", + " pm.expect(jsonData[\"timeout\"]).to.be.empty;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/last_completed", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "last_completed" + ] + } + }, + "response": [] + }, + { + "name": "Read Results", + "event": [ + { + "listen": "test", + "script": { + "id": "dca0b42e-9054-4354-87e5-e8d236216050", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON format is as expected\", function () {", + " for (var api of Object.keys(jsonData)) {", + " pm.expect(jsonData[api]).to.be.an.instanceof(Array);", + " for (var result of jsonData[api]) {", + " pm.expect(typeof result).to.equal(\"object\");", + " pm.expect(Object.keys(result)).to.have.lengthOf(4);", + " pm.expect(result).to.have.property(\"test\");", + " pm.expect(typeof result.test).to.equal(\"string\");", + " pm.expect(result).to.have.property(\"status\");", + " pm.expect(typeof result.status).to.equal(\"string\");", + " pm.expect(result).to.have.property(\"message\");", + " pm.expect(result.message).to.satisfy(message => !message || typeof message === \"string\");", + " pm.expect(result).to.have.property(\"subtests\");", + " pm.expect(result.subtests).to.be.an.instanceof(Array);", + " for (var subtest of result.subtests) {", + " pm.expect(typeof subtest).to.equal(\"object\");", + " pm.expect(Object.keys(subtest)).to.have.lengthOf(3);", + " pm.expect(subtest).to.have.property(\"name\");", + " pm.expect(typeof subtest.name).to.equal(\"string\");", + " pm.expect(subtest).to.have.property(\"status\");", + " pm.expect(typeof subtest.status).to.equal(\"string\");", + " pm.expect(subtest).to.have.property(\"message\");", + " pm.expect(subtest.message).to.satisfy(message => !message || typeof message === \"string\");", + " }", + " }", + " }", + "});", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "pm.test(\"Test is first and second test, successful run and failed, and successful run and passed\", function () {", + " var api = Object.keys(jsonData)[0];", + " for (var result of jsonData[api]) {", + " if (result.test === test1) {", + " pm.expect(result.test).to.equal(test1); ", + " pm.expect(result.status).to.equal(\"OK\");", + " pm.expect(result.message).to.be.null;", + " var subtest = result.subtests[0];", + " pm.expect(subtest.status).to.equal(\"FAIL\");", + " } else {", + " pm.expect(result.test).to.equal(test2); ", + " pm.expect(result.status).to.equal(\"OK\");", + " pm.expect(result.message).to.be.null;", + " subtest = result.subtests[0];", + " pm.expect(subtest.status).to.equal(\"PASS\");", + " }", + " }", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ], + "query": [ + { + "key": "path", + "value": "/2dcontext/drawing-images-to-the-canvas", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements", + "disabled": true + }, + { + "key": "path", + "value": "/2dcontext/conformance-requirements/2d.missingargs.html", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Read Results Compact", + "event": [ + { + "listen": "test", + "script": { + "id": "14ec9254-5a40-4c86-9a7f-72f43a35a79b", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(typeof jsonData).to.equal(\"object\");", + " for (var api of Object.keys(jsonData)) {", + " pm.expect(jsonData[api]).to.have.property(\"pass\");", + " pm.expect(typeof jsonData[api].pass).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"fail\");", + " pm.expect(typeof jsonData[api].fail).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"timeout\");", + " pm.expect(typeof jsonData[api].timeout).to.equal(\"number\");", + " pm.expect(jsonData[api]).to.have.property(\"not_run\");", + " pm.expect(typeof jsonData[api].not_run).to.equal(\"number\");", + " }", + "})", + "", + "const test1 = pm.globals.get(\"single_test_1\");", + "const test2 = pm.globals.get(\"single_test_2\");", + "", + "var test1Api = test1.split(\"/\").find(part => !!part);", + "var test2Api = test1.split(\"/\").find(part => !!part);", + "", + "pm.test(\"Responds with one test failed\", function () {", + " pm.expect(Object.keys(jsonData)).to.have.lengthOf(2);", + " var api = Object.keys(jsonData)[0];", + " if (api === test1Api) {", + " pm.expect(jsonData[api].pass).to.equal(0);", + " pm.expect(jsonData[api].fail).to.equal(1);", + " } else {", + " pm.expect(jsonData[api].pass).to.equal(1);", + " pm.expect(jsonData[api].fail).to.equal(0);", + " }", + " pm.expect(jsonData[api].timeout).to.equal(0);", + " pm.expect(jsonData[api].not_run).to.equal(0);", + " api = Object.keys(jsonData)[1];", + " if (api === test1Api) {", + " pm.expect(jsonData[api].pass).to.equal(0);", + " pm.expect(jsonData[api].fail).to.equal(1);", + " } else {", + " pm.expect(jsonData[api].pass).to.equal(1);", + " pm.expect(jsonData[api].fail).to.equal(0);", + " }", + " pm.expect(jsonData[api].timeout).to.equal(0);", + " pm.expect(jsonData[api].not_run).to.equal(0);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/compact", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "compact" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "132574dc-3688-47e3-8f50-3235f18806f7", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(Object.keys(response)).to.have.lengthOf(1);", + " pm.expect(response).to.have.property(\"next_test\");", + " pm.expect(typeof response.next_test).to.equal(\"string\");", + "});", + "", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);", + "", + "const web_root = pm.environment.get(\"web_root\");", + "", + "pm.test(\"Returned test finish page\", function () {", + " pm.expect(test).to.equal(\"/\" + web_root + \"/finish.html\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Clean Up", + "item": [ + { + "name": "Delete Session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Viewing and Downloading Reports", + "item": [ + { + "name": "Create Sessions", + "item": [ + { + "name": "First Session", + "item": [ + { + "name": "Create Session One Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "2f233dcf-d934-4479-8908-b1349e6ea54d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "2930a821-2c6e-47b9-89d9-90ebe1cff52a", + "exec": [ + "const availableTests = pm.globals.get(\"available_tests\");", + "const test1 = availableTests[Object.keys(availableTests)[0]][0];", + "const test2 = availableTests[Object.keys(availableTests)[0]][1];", + "const apiName = test1.split(\"/\").filter(part => !!part)[0];", + "", + "pm.globals.set(\"single_test_1\", test1);", + "pm.globals.set(\"single_test_2\", test2);", + "pm.globals.set(\"api_name\", apiName);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": [\"{{single_test_1}}\"]\n }\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "12f3616b-707e-4a71-8db8-89fc195c1fcd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "f35f1509-383f-49af-a30e-41e1df4efa04", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "event": [ + { + "listen": "test", + "script": { + "id": "b015f161-e390-4224-9f26-92395f44c772", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"FAIL\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Second Session", + "item": [ + { + "name": "Create Session One Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "da3d0c17-6b2b-4d61-ad01-dba736425388", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token_comp\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "7da81e81-d344-4459-b700-19b93d49d3c9", + "exec": [ + "const availableTests = pm.globals.get(\"available_tests\");", + "const test1 = availableTests[Object.keys(availableTests)[0]][0];", + "const test2 = availableTests[Object.keys(availableTests)[0]][1];", + "", + "pm.globals.set(\"single_test_1\", test1);", + "pm.globals.set(\"single_test_2\", test2);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": [\"{{single_test_1}}\"]\n }\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Start Session", + "event": [ + { + "listen": "test", + "script": { + "id": "3296c7ba-67a6-405d-a78a-51dd64432301", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token_comp}}/start", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token_comp}}", + "start" + ] + } + }, + "response": [] + }, + { + "name": "Read Next Test of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "72deb55c-4583-4741-9cf8-97713762b894", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const response = pm.response.json();", + "", + "const nextTest = response.next_test;", + "pm.globals.set(\"current_test_url\", nextTest);", + "if (!nextTest) return;", + "const test = \"/\" + nextTest.split(\"/\").slice(3).join(\"/\").split(\"?\")[0];", + "pm.globals.set(\"current_test\", test);", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token_comp}}/next", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token_comp}}", + "next" + ] + } + }, + "response": [] + }, + { + "name": "Create Result", + "event": [ + { + "listen": "test", + "script": { + "id": "d695f300-a773-4654-b346-95c536cad19e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"test\": \"{{current_test}}\",\n \"status\": \"OK\",\n \"message\": null,\n \"subtests\": [\n {\n \"name\": \"Subtest testing feature xy\",\n \"status\": \"FAIL\",\n \"message\": \"Error message\"\n }\n ]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token_comp}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token_comp}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Download reports", + "item": [ + { + "name": "Download Results Overview", + "event": [ + { + "listen": "test", + "script": { + "id": "6838965f-7a27-48d5-8c27-f55d4756588f", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/overview", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "overview" + ] + } + }, + "response": [] + }, + { + "name": "Download All Apis Json", + "event": [ + { + "listen": "test", + "script": { + "id": "bcc2c8c4-94c0-4227-a627-3e0d5be2e7b8", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/json", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "json" + ] + } + }, + "response": [] + }, + { + "name": "Download WPT Multi Report Url", + "event": [ + { + "listen": "test", + "script": { + "id": "7b370723-0506-4b5e-941a-f31a628a29f6", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Uri returned\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(typeof jsonData.uri).to.equal(\"string\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{api_name}}/reporturl?tokens={{session_token}},{{session_token_comp}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{api_name}}", + "reporturl" + ], + "query": [ + { + "key": "tokens", + "value": "{{session_token}},{{session_token_comp}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Download Results Api Json", + "event": [ + { + "listen": "test", + "script": { + "id": "b5243979-b63a-4bbf-bd51-1529da1e1f6d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "81f3da29-8a0c-4403-929d-86590b01ef2f", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/{{api_name}}/json", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "{{api_name}}", + "json" + ] + } + }, + "response": [] + }, + { + "name": "Download WPT Report Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "0168ea3f-9bf7-4ea7-a3ad-745c2704d97e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Uri returned\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(typeof jsonData.uri).to.equal(\"string\");", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "e4efdac9-2d00-4853-b145-18a6d44ff139", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/results/{{session_token}}/{{api_name}}/reporturl", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "results", + "{{session_token}}", + "{{api_name}}", + "reporturl" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Malfunctioning List", + "item": [ + { + "name": "Create Session \\w Configuration Copy", + "event": [ + { + "listen": "test", + "script": { + "id": "e685a989-8ef7-4e8f-a3c7-b579c66430f9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "8517360b-2e66-4ca9-9339-017622c39888", + "exec": [ + "var automaticTimeout = 120000;", + "var manualTimeout = 1000000;", + "var specialTimeout = 2000;", + "", + "pm.globals.set(\"automatic_timeout\", automaticTimeout);", + "pm.globals.set(\"manual_timeout\", manualTimeout);", + "pm.globals.set(\"special_timeout\", specialTimeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": {{included_tests}},\n \"exclude\": {{excluded_tests}}\n },\n \"types\": [\n \"automatic\"\n ],\n \"timeouts\": {\n \"automatic\": {{automatic_timeout}},\n \"manual\": {{manual_timeout}},\n \"{{special_timeout_test}}\": {{special_timeout}}\n },\n \"labels\": [\"label1\", \"label2\"]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Malfunctioning Empty", + "event": [ + { + "listen": "test", + "script": { + "id": "4e85ecaf-4364-4681-ab8a-221d40681c44", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"Return empty array\", function() {", + " pm.expect(jsonData).to.be.an.instanceof(Array)", + " pm.expect(jsonData).to.have.length(0)", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/malfunctioning", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "malfunctioning" + ] + } + }, + "response": [] + }, + { + "name": "Update Session Malfunctioning Insert Two", + "event": [ + { + "listen": "test", + "script": { + "id": "a6221560-9eba-4fb4-a7cb-a1570a37425d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "[\n\t\"/test/file/one.html\",\n\t\"/test/file/two.html\"\n]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/malfunctioning", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "malfunctioning" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Malfunctioning Two Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "77d14567-4600-44fd-98e4-99e113da6781", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"Return array with two tests\", function() {", + " pm.expect(jsonData).to.be.an.instanceof(Array)", + " pm.expect(jsonData).to.have.length(2)", + " pm.expect(jsonData).to.include(\"/test/file/one.html\")", + " pm.expect(jsonData).to.include(\"/test/file/two.html\")", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/malfunctioning", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "malfunctioning" + ] + } + }, + "response": [] + }, + { + "name": "Update Session Malfunctioning Empty Array", + "event": [ + { + "listen": "test", + "script": { + "id": "55b486da-c5ae-49d4-b11a-247387267c9a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "[]", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/malfunctioning", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "malfunctioning" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Malfunctioning Empty", + "event": [ + { + "listen": "test", + "script": { + "id": "953002ec-d8df-477a-a0dc-f4e4a2efd031", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"Return empty array\", function() {", + " pm.expect(jsonData).to.be.an.instanceof(Array)", + " pm.expect(jsonData).to.have.length(0)", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}/malfunctioning", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}", + "malfunctioning" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Devices API", + "item": [ + { + "name": "create", + "item": [ + { + "name": "Create device", + "event": [ + { + "listen": "test", + "script": { + "id": "286426ec-c394-48a4-a90f-c6dd80c7bef1", + "exec": [ + "pm.test(\"Successful POST request\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200,201,202]);", + "});", + "", + "var response = pm.response.json();", + "", + "pm.test('Schema is valid', function() {", + " pm.expect(response).to.have.property(\"token\");", + "});", + "", + "pm.test('Data is valid', function() {", + " pm.expect(typeof response.token).to.equal(\"string\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Wait device timeout", + "event": [ + { + "listen": "test", + "script": { + "id": "3bdb0f7c-1261-465e-9b02-0070005f0c43", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "a1cf5880-7b8e-4bc6-9d92-59632a719c54", + "exec": [ + "var timeout = parseInt(pm.environment.get(\"device_timeout\")) + 500", + "", + "setTimeout(function () {}, timeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "read device", + "item": [ + { + "name": "Device not found", + "item": [ + { + "name": "Read device", + "event": [ + { + "listen": "test", + "script": { + "id": "a4401cbc-0a3a-4c2d-b1ed-e7d6867614ff", + "exec": [ + "pm.test(\"Successful GET request\", function () {", + " pm.expect(pm.response.code).to.equal(404);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "1644fd70-b4c4-4207-8e12-67752a984417", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/invalid_token", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "invalid_token" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Device found", + "item": [ + { + "name": "Prep: Create device", + "event": [ + { + "listen": "test", + "script": { + "id": "c4f14137-5ced-449b-a872-b7d541e2f6af", + "exec": [ + "var response = pm.response.json();", + "var token = response.token;", + "", + "pm.globals.set(\"device_token\", token)" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Read device", + "event": [ + { + "listen": "test", + "script": { + "id": "61a840f1-d3cd-4d7a-a54f-30da1266e48f", + "exec": [ + "pm.test(\"Successful GET request\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200]);", + "});", + "", + "var response = pm.response.json();", + "", + "pm.test('Schema is valid', function() {", + " pm.expect(response).to.have.property(\"token\");", + " pm.expect(response).to.have.property(\"user_agent\");", + " pm.expect(response).to.have.property(\"last_active\");", + " pm.expect(response).to.have.property(\"name\");", + "});", + "", + "pm.test('Data is valid', function() {", + " pm.expect(typeof response.token).to.equal(\"string\");", + " pm.expect(typeof response.user_agent).to.equal(\"string\");", + " pm.expect(typeof response.last_active).to.equal(\"string\");", + " pm.expect(typeof response.name).to.equal(\"string\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/{{device_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "{{device_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Wait device timeout", + "event": [ + { + "listen": "test", + "script": { + "id": "17112336-b962-472d-86a8-7872ff9876d1", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "912939cc-1685-4e1f-b0a6-696b264870ca", + "exec": [ + "var timeout = parseInt(pm.environment.get(\"device_timeout\")) + 500", + "", + "setTimeout(function () {}, timeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Timed out device", + "item": [ + { + "name": "Prep: Create device", + "event": [ + { + "listen": "test", + "script": { + "id": "c99b9318-1e50-4702-9d81-53d87faa1080", + "exec": [ + "var response = pm.response.json();", + "var token = response.token;", + "", + "pm.globals.set(\"device_token\", token)" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Wait device timeout", + "event": [ + { + "listen": "test", + "script": { + "id": "89517dc9-31b4-40e7-89e4-99dd6e792e6a", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "ed20bbf6-4f31-4d91-a07b-7a0b4afcf161", + "exec": [ + "var timeout = parseInt(pm.environment.get(\"device_timeout\")) + 500", + "", + "setTimeout(function () {}, timeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Read device", + "event": [ + { + "listen": "test", + "script": { + "id": "7b7496f5-2fdc-470c-b394-2a5ae7d29da2", + "exec": [ + "pm.test(\"Successful GET request\", function () {", + " pm.expect(pm.response.code).to.equal(404);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "1807f152-7ef4-4277-9db6-1bff53d6cc8b", + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/{{device_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "{{device_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "read devices", + "item": [ + { + "name": "Prep: Create device A", + "event": [ + { + "listen": "test", + "script": { + "id": "a7803c5c-f371-4ae0-8b08-1c06995c9b60", + "exec": [ + "var response = pm.response.json();", + "var token = response.token;", + "", + "pm.globals.set(\"device_token_a\", token)" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Prep: Create device B", + "event": [ + { + "listen": "test", + "script": { + "id": "02450903-aef9-4ee6-9d48-94ba9b5fd54c", + "exec": [ + "var response = pm.response.json();", + "var token = response.token;", + "", + "pm.globals.set(\"device_token_b\", token)" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Read devices", + "event": [ + { + "listen": "test", + "script": { + "id": "1612417b-bed8-48d5-a6a3-39d0d0fe6932", + "exec": [ + "pm.test(\"Successful GET request\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200]);", + "});", + "", + "var response = pm.response.json();", + "", + "pm.test('Schema is valid', function() {", + " pm.expect(response).to.be.instanceof(Array);", + " response.forEach(element => {", + " pm.expect(element).to.have.property(\"token\");", + " pm.expect(element).to.have.property(\"user_agent\");", + " pm.expect(element).to.have.property(\"last_active\");", + " pm.expect(element).to.have.property(\"name\");", + " })", + "});", + "", + "pm.test('Data is valid', function() {", + " pm.expect(response).to.have.lengthOf(2);", + " var devices_left = [", + " pm.globals.get(\"device_token_a\"), ", + " pm.globals.get(\"device_token_b\")", + " ]", + " response.forEach(element => {", + " pm.expect(typeof element.token).to.equal(\"string\");", + " pm.expect(typeof element.user_agent).to.equal(\"string\");", + " pm.expect(typeof element.last_active).to.equal(\"string\");", + " pm.expect(typeof element.name).to.equal(\"string\");", + " pm.expect(devices_left).to.include(element.token);", + " devices_left.splice(devices_left.indexOf(element.token), 1);", + " })", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Wait device timeout", + "event": [ + { + "listen": "test", + "script": { + "id": "9b7ff623-8aac-46d1-9c56-1ceb8acc2de6", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "c0fbf742-f75e-4f3b-a576-75c9d5e0f72d", + "exec": [ + "var timeout = parseInt(pm.environment.get(\"device_timeout\")) + 500", + "", + "setTimeout(function () {}, timeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/devices/", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "devices", + "" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Sessions API", + "item": [ + { + "name": "create session", + "item": [ + { + "name": "With Defaults", + "item": [ + { + "name": "Prep: Read Available Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "fc15d329-d132-4abf-90e4-f549eee99b60", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var availableTests = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(typeof availableTests).to.equal(\"object\");", + " for (var api of Object.keys(availableTests)) {", + " pm.expect(availableTests[api]).to.be.an.instanceof(Array);", + " var apiRegExp = new RegExp(\"^/\" + api, \"i\");", + " for (var test of availableTests[api]) {", + " pm.expect(test).to.match(apiRegExp);", + " }", + " }", + "});", + "", + "var includedTests = [];", + "var excludedTests = [];", + "var specialTimeoutTest = \"\";", + "", + "var apis = Object.keys(availableTests);", + "for(var api of apis) {", + " if (availableTests[api].length > 50) {", + " var subDirs = availableTests[api].map(test => test.split(\"/\").filter(part => !!part).join(\"/\").split(\"/\")[1]).reduce((acc, curr) => acc.indexOf(curr) === -1 ? acc.concat([curr]) : acc, []);", + " if (subDirs.length > 2) {", + " includedTests.push(\"/\" + api);", + " excludedTests.push(\"/\" + api + \"/\" + subDirs[0]);", + " specialTimeoutTest = availableTests[api][availableTests[api].length - 1];", + " break;", + " }", + " ", + " }", + "}", + "", + "pm.globals.set(\"available_tests\", availableTests);", + "pm.globals.set(\"included_tests\", JSON.stringify(includedTests));", + "pm.globals.set(\"excluded_tests\", JSON.stringify(excludedTests));", + "pm.globals.set(\"special_timeout_test\", specialTimeoutTest.replace(\".\", \"\"));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests" + ] + } + }, + "response": [] + }, + { + "name": "Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "ebb192ce-48e5-4aac-b99d-68894378eac8", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "159976cd-de00-4f88-8f9f-47db13ca4a30", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Configuration is default\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " pm.expect(jsonData.tests.include).to.include(\"/\");", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(60000);", + " pm.expect(jsonData.timeouts.manual).to.equal(300000);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + " pm.expect(jsonData.labels).to.be.empty;", + " pm.expect(new Date(jsonData.date_created).getTime()).to.be.below(Date.now());", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "5058b07b-5e55-44e0-ad88-5c7b5884fa3c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"Session status is pending\", function () {", + " pm.expect(jsonData.status).to.equal(\"pending\");", + "})", + "", + "pm.test(\"Start, Finish and Expiration date not set\", function () {", + " pm.expect(jsonData.date_started).to.be.null;", + " pm.expect(jsonData.date_finished).to.be.null;", + " pm.expect(jsonData.expiration_date).to.be.null;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "62a8c853-bf0b-47b0-9cee-7611d2b48cde", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"pending_tests\");", + " pm.expect(typeof jsonData.pending_tests).to.equal(\"object\");", + " pm.expect(jsonData).to.have.property(\"running_tests\");", + " pm.expect(typeof jsonData.running_tests).to.equal(\"object\");", + "});", + "", + "pm.test(\"All tests are pending tests\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.not.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})", + "", + "const availableTests = pm.globals.get(\"available_tests\"); ", + "", + "pm.test(\"All available tests are part of the session\", function () {", + " for (var api of Object.keys(jsonData.pending_tests)) {", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(availableTests[api]).to.include(test);", + " }", + " }", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "878420c3-575a-4194-9a72-cebe07823674", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "6672030f-5a8a-4bea-9792-c24b980392e9", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "With Configuration", + "item": [ + { + "name": "Prep: Read Available Tests", + "event": [ + { + "listen": "test", + "script": { + "id": "504b76ca-6870-443c-8c33-0cccc52cddae", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var availableTests = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(typeof availableTests).to.equal(\"object\");", + " for (var api of Object.keys(availableTests)) {", + " pm.expect(availableTests[api]).to.be.an.instanceof(Array);", + " var apiRegExp = new RegExp(\"^/\" + api, \"i\");", + " for (var test of availableTests[api]) {", + " pm.expect(test).to.match(apiRegExp);", + " }", + " }", + "});", + "", + "var includedTests = [];", + "var excludedTests = [];", + "var specialTimeoutTest = \"\";", + "", + "var apis = Object.keys(availableTests);", + "for(var api of apis) {", + " if (availableTests[api].length > 50) {", + " var subDirs = availableTests[api].map(test => test.split(\"/\").filter(part => !!part).join(\"/\").split(\"/\")[1]).reduce((acc, curr) => acc.indexOf(curr) === -1 ? acc.concat([curr]) : acc, []);", + " if (subDirs.length > 2) {", + " includedTests.push(\"/\" + api);", + " excludedTests.push(\"/\" + api + \"/\" + subDirs[0]);", + " specialTimeoutTest = availableTests[api][availableTests[api].length - 1];", + " break;", + " }", + " ", + " }", + "}", + "", + "pm.globals.set(\"available_tests\", availableTests);", + "pm.globals.set(\"included_tests\", JSON.stringify(includedTests));", + "pm.globals.set(\"excluded_tests\", JSON.stringify(excludedTests));", + "pm.globals.set(\"special_timeout_test\", specialTimeoutTest.replace(\".\", \"\"));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests" + ] + } + }, + "response": [] + }, + { + "name": "Create Session \\w Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "fa956871-503a-421c-9822-4e2a11e1cf1c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "213bdf59-9f98-4b5e-bacc-ae3cb31ae26a", + "exec": [ + "var automaticTimeout = 120000;", + "var manualTimeout = 1000000;", + "var specialTimeout = 2000;", + "", + "pm.globals.set(\"automatic_timeout\", automaticTimeout);", + "pm.globals.set(\"manual_timeout\", manualTimeout);", + "pm.globals.set(\"special_timeout\", specialTimeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"tests\": {\n \"include\": {{included_tests}},\n \"exclude\": {{excluded_tests}}\n },\n \"types\": [\n \"automatic\"\n ],\n \"timeouts\": {\n \"automatic\": {{automatic_timeout}},\n \"manual\": {{manual_timeout}},\n \"{{special_timeout_test}}\": {{special_timeout}}\n },\n \"labels\": [\"label1\", \"label2\"]\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "2656b209-57d8-4f39-8db1-ce3376e8a532", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "var includedTests = JSON.parse(pm.globals.get(\"included_tests\"));", + "var excludedTests = JSON.parse(pm.globals.get(\"excluded_tests\"));", + "var automaticTimeout = pm.globals.get(\"automatic_timeout\");", + "var manualTimeout = pm.globals.get(\"manual_timeout\");", + "var specialTimeout = pm.globals.get(\"special_timeout\");", + "var specialTimeoutTest = pm.globals.get(\"special_timeout_test\");", + "", + "pm.test(\"Configuration is as specified\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " for (var test of includedTests) {", + " pm.expect(jsonData.tests.include).to.include(test);", + " }", + " for (var test of excludedTests) {", + " pm.expect(jsonData.tests.exclude).to.include(test);", + " }", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.not.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(automaticTimeout);", + " pm.expect(jsonData.timeouts.manual).to.equal(manualTimeout);", + " pm.expect(jsonData.timeouts[specialTimeoutTest]).to.equal(specialTimeout);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + " pm.expect(jsonData.labels).to.include(\"label1\");", + " pm.expect(jsonData.labels).to.include(\"label2\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "2a7524e5-7394-4177-8267-42d5b32bc474", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"Session status is pending\", function () {", + " pm.expect(jsonData.status).to.equal(\"pending\");", + "})", + "", + "pm.test(\"Start and Finish date not set\", function () {", + " pm.expect(jsonData.date_started).to.be.null;", + " pm.expect(jsonData.date_finished).to.be.null;", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Read Tests of Session", + "event": [ + { + "listen": "test", + "script": { + "id": "448b6a0c-135d-42ef-8bc0-b4b1ce4ab8a0", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"All tests are pending tests\", function () {", + " pm.expect(Object.keys(jsonData.pending_tests)).to.not.have.lengthOf(0);", + " pm.expect(Object.keys(jsonData.running_tests)).to.have.lengthOf(0);", + "})", + "", + "const availableTests = pm.globals.get(\"available_tests\");", + "const includedTests = pm.globals.get(\"included_tests\");", + "const excludedTests = pm.globals.get(\"excluded_tests\");", + "", + "pm.test(\"Selected subset of tests are part of the session\", function () {", + " for (var api of Object.keys(jsonData.pending_tests)) {", + " for (var includedTest of includedTests) {", + " if (includedTest.split(\"/\").find(part => !!part) === api) {", + " var includeRegExp = new RegExp(\"^\" + includedTest, \"i\");", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(test).to.match(regex);", + " }", + " break;", + " }", + " }", + " for (var excludedTest of excludedTests) {", + " if (excludedTest.split(\"/\").find(part => !!part) === api) {", + " var excludeRegExp = new RegExp(\"^\" + excludedTest, \"i\");", + " for (var test of jsonData.pending_tests[api]) {", + " pm.expect(test).to.not.match(regex);", + " }", + " break;", + " }", + " }", + " }", + "});", + "", + "const sessionTests = jsonData.pending_tests;", + "", + "pm.globals.set(\"session_tests\", JSON.stringify(sessionTests));" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/tests/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "tests", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "a16eac8e-9609-4314-abd8-a5c470537b52", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "5df55957-0bbb-4db8-9ab9-d8a70ce37bc5", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "With Expiration", + "item": [ + { + "name": "Create Session With Expiration", + "event": [ + { + "listen": "test", + "script": { + "id": "6c4aa702-ae3a-44a4-b886-b3e883de4d32", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "893672a9-c666-4790-b6a7-e0ce7afda482", + "exec": [ + "var expirationDate = Date.now() + 3000;", + "pm.globals.set(\"expiration_date\", expirationDate);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"expiration_date\": {{expiration_date}}\n}" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Expired Session", + "event": [ + { + "listen": "test", + "script": { + "id": "f6b31d37-a98b-4110-80a2-f78db6f2e26f", + "exec": [ + "pm.test(\"Status code is 404\", function () {", + " pm.response.to.have.status(404);", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "id": "d41cf31b-c8e8-455f-aa69-527af5fbd66b", + "exec": [ + "var expirationDate = pm.globals.get(\"expiration_date\");", + "", + "var timeout = expirationDate - Date.now() + 1000", + "", + "console.log(timeout)", + "", + "setTimeout(function () {}, timeout);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "read session", + "item": [ + { + "name": "Prep: Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "090ca1bc-cbee-4d7b-b19f-fc1f4bb879a0", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "232aff11-3cdc-4994-af42-5e3574583814", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"tests\");", + " pm.expect(typeof jsonData.tests).to.equal(\"object\");", + " pm.expect(jsonData.tests).to.have.property(\"include\");", + " pm.expect(jsonData.tests.include).to.be.an.instanceof(Array);", + " pm.expect(jsonData.tests).to.have.property(\"exclude\");", + " pm.expect(jsonData.tests.exclude).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"types\");", + " pm.expect(jsonData.types).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"user_agent\");", + " pm.expect(typeof jsonData.user_agent).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"timeouts\");", + " pm.expect(typeof jsonData.timeouts).to.equal(\"object\")", + " pm.expect(jsonData.timeouts).to.have.property(\"automatic\");", + " pm.expect(typeof jsonData.timeouts.automatic).to.equal(\"number\");", + " pm.expect(jsonData.timeouts).to.have.property(\"manual\");", + " pm.expect(typeof jsonData.timeouts.manual).to.equal(\"number\");", + " pm.expect(jsonData).to.have.property(\"browser\");", + " pm.expect(typeof jsonData.browser).to.equal(\"object\");", + " pm.expect(jsonData.browser).to.have.property(\"name\");", + " pm.expect(typeof jsonData.browser.name).to.equal(\"string\");", + " pm.expect(jsonData.browser).to.have.property(\"version\");", + " pm.expect(typeof jsonData.browser.version).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"reference_tokens\");", + " pm.expect(jsonData.reference_tokens).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"labels\");", + " pm.expect(jsonData.labels).to.be.an.instanceof(Array);", + " pm.expect(jsonData).to.have.property(\"date_created\");", + "});", + "", + "pm.test(\"Configuration is default\", function () {", + " pm.expect(jsonData.token).to.match(tokenRegex);", + " pm.expect(jsonData.tests.include).to.include(\"/\");", + " pm.expect(jsonData.types).to.include(\"automatic\");", + " pm.expect(jsonData.types).to.include(\"manual\");", + " pm.expect(jsonData.user_agent).to.include(\"PostmanRuntime\");", + " pm.expect(jsonData.timeouts.automatic).to.equal(60000);", + " pm.expect(jsonData.timeouts.manual).to.equal(300000);", + " pm.expect(jsonData.browser.name).to.equal(\"Other\");", + " pm.expect(jsonData.browser.version).to.equal(\"0\");", + " pm.expect(jsonData.is_public).to.equal(false);", + " pm.expect(jsonData.reference_tokens).to.be.empty;", + " pm.expect(jsonData.labels).to.be.empty;", + " pm.expect(new Date(jsonData.date_created).getTime()).to.be.below(Date.now());", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "read session status", + "item": [ + { + "name": "Prep: Create Session No Configuration", + "event": [ + { + "listen": "test", + "script": { + "id": "73cbeeb0-019b-4331-b0ec-ef9d3f1e0494", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "const tokenRegex = new RegExp(\"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$\");", + "", + "pm.test(\"Responds with token in JSON format\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(jsonData.token).to.match(tokenRegex);", + "});", + "", + "", + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read Session Status", + "event": [ + { + "listen": "test", + "script": { + "id": "ba142b55-2454-4472-bcf9-669b0bb7bab9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"token\");", + " pm.expect(typeof jsonData.token).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"status\");", + " pm.expect(typeof jsonData.status).to.equal(\"string\");", + " pm.expect(jsonData).to.have.property(\"expiration_date\");", + " pm.expect(jsonData.expiration_date).to.be.null;", + " pm.expect(jsonData).to.have.property(\"date_started\");", + " pm.expect(jsonData).to.have.property(\"date_finished\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}", + "status" + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "read sessions", + "item": [ + { + "name": "Without query parameters", + "item": [ + { + "name": "Read sessions", + "event": [ + { + "listen": "test", + "script": { + "id": "f443955f-b57e-4801-8eac-547597381615", + "exec": [ + "const response = pm.response.json();", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"JSON structure as expected\", function() {", + " pm.expect(response).to.have.property(\"items\");", + " pm.expect(response[\"items\"]).to.be.instanceof(Array);", + " pm.expect(response).to.have.property(\"_links\");", + " pm.expect(response[\"_links\"]).to.be.instanceof(Object);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/_wave/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "_wave", + "api", + "sessions" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "Containing created session", + "item": [ + { + "name": "Prep: Create session", + "event": [ + { + "listen": "test", + "script": { + "id": "2ca80dee-f9a5-4e0b-bead-6ab871d9edf8", + "exec": [ + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read sessions", + "event": [ + { + "listen": "test", + "script": { + "id": "fbf5eafb-0ae7-4105-8df5-51bb53b0c595", + "exec": [ + "const token = pm.globals.get(\"session_token\");", + "const response = pm.response.json();", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"JSON structure as expected\", function() {", + " pm.expect(response).to.have.property(\"items\");", + " pm.expect(response[\"items\"]).to.be.instanceof(Array);", + " pm.expect(response).to.have.property(\"_links\");", + " pm.expect(response[\"_links\"]).to.be.instanceof(Object);", + "});", + "", + "pm.test(\"Created session's token in response\", function() {", + " pm.expect(response.items).to.contain(token);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/_wave/api/sessions?index=0&count=1000", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "_wave", + "api", + "sessions" + ], + "query": [ + { + "key": "index", + "value": "0" + }, + { + "key": "count", + "value": "1000" + } + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete Session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "With configuration expansion", + "item": [ + { + "name": "Prep: Create session", + "event": [ + { + "listen": "test", + "script": { + "id": "bdd64594-c874-4eb2-8b36-4c37cea0f0cb", + "exec": [ + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read sessions", + "event": [ + { + "listen": "test", + "script": { + "id": "6732aedf-d99d-416f-b93d-98bc0404ef61", + "exec": [ + "const token = pm.globals.get(\"session_token\");", + "const response = pm.response.json();", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"JSON structure as expected\", function() {", + " pm.expect(response).to.have.property(\"items\");", + " pm.expect(response[\"items\"]).to.be.instanceof(Array);", + " pm.expect(response).to.have.property(\"_links\");", + " pm.expect(response[\"_links\"]).to.be.instanceof(Object);", + " pm.expect(response).to.have.property(\"_embedded\");", + " pm.expect(response[\"_embedded\"]).to.be.instanceof(Object);", + " pm.expect(response[\"_embedded\"]).to.have.property(\"configuration\");", + " pm.expect(response[\"_embedded\"][\"configuration\"]).to.be.instanceof(Array);", + "});", + "", + "pm.test(\"Created session's token in response\", function() {", + " pm.expect(response.items).to.contain(token);", + "});", + "", + "pm.test(\"Created session's token in embedded configuration\", function() {", + " let tokenInConfigurationList = false;", + " let configurations = response._embedded.configuration;", + " for (let configuration of configurations) {", + " if (configuration.token !== token) continue;", + " tokenInConfigurationList = true;", + " }", + " pm.expect(tokenInConfigurationList).to.equal(true);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/_wave/api/sessions?index=0&count=1000&expand=configuration", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "_wave", + "api", + "sessions" + ], + "query": [ + { + "key": "index", + "value": "0" + }, + { + "key": "count", + "value": "1000" + }, + { + "key": "expand", + "value": "configuration" + } + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete Session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + }, + { + "name": "With status expansion", + "item": [ + { + "name": "Prep: Create session", + "event": [ + { + "listen": "test", + "script": { + "id": "3319e417-dd54-495f-a452-5519d2a61082", + "exec": [ + "const response = pm.response.json();", + "const token = response.token;", + "pm.globals.set(\"session_token\", token);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions" + ] + } + }, + "response": [] + }, + { + "name": "Read sessions", + "event": [ + { + "listen": "test", + "script": { + "id": "6ca3480a-3224-4bf8-a466-fdcb06338795", + "exec": [ + "const token = pm.globals.get(\"session_token\");", + "const response = pm.response.json();", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"JSON structure as expected\", function() {", + " pm.expect(response).to.have.property(\"items\");", + " pm.expect(response[\"items\"]).to.be.instanceof(Array);", + " pm.expect(response).to.have.property(\"_links\");", + " pm.expect(response[\"_links\"]).to.be.instanceof(Object);", + " pm.expect(response).to.have.property(\"_embedded\");", + " pm.expect(response[\"_embedded\"]).to.be.instanceof(Object);", + " pm.expect(response[\"_embedded\"]).to.have.property(\"status\");", + " pm.expect(response[\"_embedded\"][\"status\"]).to.be.instanceof(Array);", + "});", + "", + "pm.test(\"Created session's token in response\", function() {", + " pm.expect(response.items).to.contain(token);", + "});", + "", + "pm.test(\"Created session's token in embedded status\", function() {", + " let tokenInStatusList = false;", + " let statuses = response._embedded.status;", + " for (let status of statuses) {", + " if (status.token !== token) continue;", + " tokenInStatusList = true;", + " }", + " pm.expect(tokenInStatusList).to.equal(true);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/_wave/api/sessions?index=0&count=1000&expand=status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "_wave", + "api", + "sessions" + ], + "query": [ + { + "key": "index", + "value": "0" + }, + { + "key": "count", + "value": "1000" + }, + { + "key": "expand", + "value": "status" + } + ] + } + }, + "response": [] + }, + { + "name": "Clean up: Delete Session", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/sessions/{{session_token}}", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "sessions", + "{{session_token}}" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "General API", + "item": [ + { + "name": "server status", + "item": [ + { + "name": "Read server status", + "event": [ + { + "listen": "test", + "script": { + "id": "8b5b4c23-db0a-4b81-9349-ce8ead64bb7a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var jsonData = pm.response.json();", + "", + "pm.test(\"JSON structure is as expected\", function () {", + " pm.expect(jsonData).to.have.property(\"import_results_enabled\");", + " pm.expect(typeof jsonData.import_results_enabled).to.equal(\"boolean\");", + " pm.expect(jsonData).to.have.property(\"reports_enabled\");", + " pm.expect(typeof jsonData.reports_enabled).to.equal(\"boolean\");", + " pm.expect(jsonData).to.have.property(\"read_sessions_enabled\");", + " pm.expect(typeof jsonData.read_sessions_enabled).to.equal(\"boolean\");", + " pm.expect(jsonData).to.have.property(\"version_string\");", + " pm.expect(typeof jsonData.version_string).to.equal(\"string\");", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{protocol}}://{{host}}:{{port}}/{{web_root}}/api/status", + "protocol": "{{protocol}}", + "host": [ + "{{host}}" + ], + "port": "{{port}}", + "path": [ + "{{web_root}}", + "api", + "status" + ] + } + }, + "response": [] + } + ], + "protocolProfileBehavior": {}, + "_postman_isSubFolder": true + } + ], + "protocolProfileBehavior": {} + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/tests/test_wave.py b/tests/wpt/web-platform-tests/tools/wave/tests/test_wave.py new file mode 100644 index 00000000000..d060fdd19f2 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/tests/test_wave.py @@ -0,0 +1,54 @@ +import errno +import os +import socket +import subprocess +import time + +try: + from urllib.request import urlopen + from urllib.error import URLError +except ImportError: + from urllib2 import urlopen, URLError + +import pytest + +from tools.wpt import wpt + +def is_port_8000_in_use(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.bind(("127.0.0.1", 8000)) + except socket.error as e: + if e.errno == errno.EADDRINUSE: + return True + else: + raise e + finally: + s.close() + return False + +def test_serve(): + if is_port_8000_in_use(): + pytest.skip("WAVE Test Runner failed: Port 8000 already in use.") + + p = subprocess.Popen([os.path.join(wpt.localpaths.repo_root, "wpt"), "serve-wave"], + preexec_fn=os.setsid) + + start = time.time() + try: + while True: + if p.poll() is not None: + assert False, "WAVE Test Runner failed: Server not running." + if time.time() - start > 6 * 60: + assert False, "WAVE Test Runner failed: Server did not start responding within 6m." + try: + resp = urlopen("http://web-platform.test:8000/_wave/api/sessions/public") + print(resp) + except URLError: + print("Server not responding, waiting another 10s.") + time.sleep(10) + else: + assert resp.code == 200 + break + finally: + os.killpg(p.pid, 15) diff --git a/tests/wpt/web-platform-tests/tools/wave/tox.ini b/tests/wpt/web-platform-tests/tools/wave/tox.ini new file mode 100644 index 00000000000..8e3e26e135b --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/tox.ini @@ -0,0 +1,20 @@ +[tox] +envlist = py27,py35,py36,py37,py38 +skipsdist=True +skip_missing_interpreters = False + +[testenv] +deps = + pytest + pytest-cov + hypothesis + mock + -r{toxinidir}/../wptrunner/requirements.txt + -r{toxinidir}/../wptrunner/requirements_chrome.txt + -r{toxinidir}/../wptrunner/requirements_firefox.txt + +commands = + pytest {posargs} + +passenv = + TASKCLUSTER_ROOT_URL diff --git a/tests/wpt/web-platform-tests/tools/wave/utils/__init__.py b/tests/wpt/web-platform-tests/tools/wave/utils/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/wpt/web-platform-tests/tools/wave/utils/deserializer.py b/tests/wpt/web-platform-tests/tools/wave/utils/deserializer.py new file mode 100644 index 00000000000..b8a36083566 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/utils/deserializer.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +from ..data.session import Session, UNKNOWN + + +def deserialize_sessions(session_dicts): + sessions = [] + for session_dict in session_dicts: + session = deserialize_session(session_dict) + sessions.append(session) + return sessions + + +def deserialize_session(session_dict): + token = "" + if "token" in session_dict: + token = session_dict["token"] + tests = {"include": [], "exclude": []} + if "tests" in session_dict: + tests = session_dict["tests"] + if "path" in session_dict: + test_paths = session_dict["path"].split(", ") + tests["include"] = tests["include"] + test_paths + types = [] + if "types" in session_dict: + types = session_dict["types"] + user_agent = "" + if "user_agent" in session_dict: + user_agent = session_dict["user_agent"] + labels = [] + if "labels" in session_dict: + labels = session_dict["labels"] + timeouts = {} + if "timeouts" in session_dict: + timeouts = session_dict["timeouts"] + pending_tests = None + if "pending_tests" in session_dict: + pending_tests = session_dict["pending_tests"] + running_tests = None + if "running_tests" in session_dict: + running_tests = session_dict["running_tests"] + status = UNKNOWN + if "status" in session_dict: + status = session_dict["status"] + test_state = None + if "test_state" in session_dict: + test_state = session_dict["test_state"] + last_completed_test = None + if "last_completed_test" in session_dict: + last_completed_test = session_dict["last_completed_test"] + date_started = None + if "date_started" in session_dict: + date_started = session_dict["date_started"] + date_finished = None + if "date_finished" in session_dict: + date_finished = session_dict["date_finished"] + is_public = False + if "is_public" in session_dict: + is_public = session_dict["is_public"] + reference_tokens = [] + if "reference_tokens" in session_dict: + reference_tokens = session_dict["reference_tokens"] + browser = None + if "browser" in session_dict: + browser = session_dict["browser"] + webhook_urls = [] + if "webhook_urls" in session_dict: + webhook_urls = session_dict["webhook_urls"] + expiration_date = None + if "expiration_date" in session_dict: + expiration_date = session_dict["expiration_date"] + malfunctioning_tests = [] + if "malfunctioning_tests" in session_dict: + malfunctioning_tests = session_dict["malfunctioning_tests"] + + return Session( + token=token, + tests=tests, + types=types, + user_agent=user_agent, + labels=labels, + timeouts=timeouts, + pending_tests=pending_tests, + running_tests=running_tests, + status=status, + test_state=test_state, + last_completed_test=last_completed_test, + date_started=date_started, + date_finished=date_finished, + is_public=is_public, + reference_tokens=reference_tokens, + browser=browser, + webhook_urls=webhook_urls, + expiration_date=expiration_date, + malfunctioning_tests=malfunctioning_tests + ) diff --git a/tests/wpt/web-platform-tests/tools/wave/utils/serializer.py b/tests/wpt/web-platform-tests/tools/wave/utils/serializer.py new file mode 100644 index 00000000000..66571738b48 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/utils/serializer.py @@ -0,0 +1,24 @@ +from __future__ import unicode_literals + +def serialize_session(session): + return { + "token": session.token, + "types": session.types, + "user_agent": session.user_agent, + "labels": session.labels, + "timeouts": session.timeouts, + "test_state": session.test_state, + "last_completed_test": session.last_completed_test, + "tests": session.tests, + "pending_tests": session.pending_tests, + "running_tests": session.running_tests, + "status": session.status, + "browser": session.browser, + "date_started": session.date_started, + "date_finished": session.date_finished, + "is_public": session.is_public, + "reference_tokens": session.reference_tokens, + "webhook_urls": session.webhook_urls, + "expiration_date": session.expiration_date, + "malfunctioning_tests": session.malfunctioning_tests + } diff --git a/tests/wpt/web-platform-tests/tools/wave/utils/user_agent_parser.py b/tests/wpt/web-platform-tests/tools/wave/utils/user_agent_parser.py new file mode 100644 index 00000000000..7c0727e1f3c --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/utils/user_agent_parser.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import +from __future__ import unicode_literals +from ua_parser import user_agent_parser + + +def parse_user_agent(user_agent_string): + user_agent = user_agent_parser.ParseUserAgent(user_agent_string) + + name = user_agent["family"] + version = "0" + + if user_agent["major"] is not None: + version = user_agent["major"] + + if user_agent["minor"] is not None: + version = version + "." + user_agent["minor"] + + if user_agent["patch"] is not None: + version = version + "." + user_agent["patch"] + + return { + "name": name, + "version": version + } + + +def abbreviate_browser_name(name): + short_names = { + "Chrome": "Ch", + "Chrome Mobile WebView": "Ch", + "Chromium": "Cm", + "WebKit": "Wk", + "Safari": "Sf", + "Firefox": "FF", + "IE": "IE", + "Edge": "Ed", + "Opera": "Op" + } + + if name in short_names: + return short_names[name] + else: + return "Xx" diff --git a/tests/wpt/web-platform-tests/tools/wave/wave_server.py b/tests/wpt/web-platform-tests/tools/wave/wave_server.py new file mode 100644 index 00000000000..cdbb9c3a675 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/wave_server.py @@ -0,0 +1,114 @@ +from __future__ import unicode_literals +import os +import logging + +from . import configuration_loader + +from .network.http_handler import HttpHandler +from .network.api.sessions_api_handler import SessionsApiHandler +from .network.api.tests_api_handler import TestsApiHandler +from .network.api.results_api_handler import ResultsApiHandler +from .network.static_handler import StaticHandler + +from .testing.sessions_manager import SessionsManager +from .testing.results_manager import ResultsManager +from .testing.tests_manager import TestsManager +from .testing.test_loader import TestLoader +from .testing.event_dispatcher import EventDispatcher + + +class WaveServer(object): + def initialize(self, + tests, + configuration_file_path=None, + application_directory_path=None, + reports_enabled=None): + if configuration_file_path is None: + configuration_file_path = "" + if application_directory_path is None: + application_directory_path = "" + if reports_enabled is None: + reports_enabled = False + + logger = logging.getLogger("wave-server") + + logger.debug("Loading configuration ...") + configuration = configuration_loader.load(configuration_file_path) + + # Initialize Managers + event_dispatcher = EventDispatcher() + sessions_manager = SessionsManager() + results_manager = ResultsManager() + tests_manager = TestsManager() + test_loader = TestLoader() + + sessions_manager.initialize( + test_loader=test_loader, + event_dispatcher=event_dispatcher, + tests_manager=tests_manager, + results_directory=configuration["results_directory_path"], + results_manager=results_manager + ) + + results_manager.initialize( + results_directory_path=configuration["results_directory_path"], + sessions_manager=sessions_manager, + tests_manager=tests_manager, + import_enabled=configuration["import_enabled"], + reports_enabled=reports_enabled, + persisting_interval=configuration["persisting_interval"] + ) + + tests_manager.initialize( + test_loader, + results_manager=results_manager, + sessions_manager=sessions_manager, + event_dispatcher=event_dispatcher + ) + + exclude_list_file_path = os.path.abspath("./excluded.json") + include_list_file_path = os.path.abspath("./included.json") + test_loader.initialize( + exclude_list_file_path, + include_list_file_path, + results_manager=results_manager, + api_titles=configuration["api_titles"] + ) + + test_loader.load_tests(tests) + + # Initialize HTTP handlers + static_handler = StaticHandler( + web_root=configuration["web_root"], + http_port=configuration["wpt_port"], + https_port=configuration["wpt_ssl_port"] + ) + sessions_api_handler = SessionsApiHandler( + sessions_manager=sessions_manager, + results_manager=results_manager, + event_dispatcher=event_dispatcher, + web_root=configuration["web_root"] + ) + tests_api_handler = TestsApiHandler( + tests_manager=tests_manager, + sessions_manager=sessions_manager, + wpt_port=configuration["wpt_port"], + wpt_ssl_port=configuration["wpt_ssl_port"], + hostname=configuration["hostname"], + web_root=configuration["web_root"], + test_loader=test_loader + ) + results_api_handler = ResultsApiHandler( + results_manager, + web_root=configuration["web_root"]) + + # Initialize HTTP server + http_handler = HttpHandler( + static_handler=static_handler, + sessions_api_handler=sessions_api_handler, + tests_api_handler=tests_api_handler, + results_api_handler=results_api_handler, + http_port=configuration["wpt_port"], + web_root=configuration["web_root"] + ) + self.handle_request = http_handler.handle_request diff --git a/tests/wpt/web-platform-tests/tools/wave/www/comparison.html b/tests/wpt/web-platform-tests/tools/wave/www/comparison.html new file mode 100644 index 00000000000..5be6da4d647 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/comparison.html @@ -0,0 +1,444 @@ + + + + + Compare Results - Web Platform Test + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/configuration.html b/tests/wpt/web-platform-tests/tools/wave/www/configuration.html new file mode 100644 index 00000000000..ae174b1a559 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/configuration.html @@ -0,0 +1,1116 @@ + + + + + + Session Configuration - Web Platform Test + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css new file mode 100644 index 00000000000..e793432ae31 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css @@ -0,0 +1,10599 @@ +/*! bulma.io v0.7.5 | MIT License | github.com/jgthms/bulma */ +@-webkit-keyframes spinAround { + from { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spinAround { + from { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +.delete, .modal-close, .is-unselectable, .button, .file, .breadcrumb, .pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis, .tabs { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.select:not(.is-multiple):not(.is-loading)::after, .navbar-link:not(.is-arrowless)::after { + border: 3px solid transparent; + border-radius: 2px; + border-right: 0; + border-top: 0; + content: " "; + display: block; + height: 0.625em; + margin-top: -0.4375em; + pointer-events: none; + position: absolute; + top: 50%; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: center; + transform-origin: center; + width: 0.625em; +} + +.box:not(:last-child), .content:not(:last-child), .notification:not(:last-child), .progress:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .title:not(:last-child), +.subtitle:not(:last-child), .block:not(:last-child), .highlight:not(:last-child), .breadcrumb:not(:last-child), .level:not(:last-child), .list:not(:last-child), .message:not(:last-child), .tabs:not(:last-child) { + margin-bottom: 1.5rem; +} + +.delete, .modal-close { + -moz-appearance: none; + -webkit-appearance: none; + background-color: rgba(10, 10, 10, 0.2); + border: none; + border-radius: 290486px; + cursor: pointer; + pointer-events: auto; + display: inline-block; + flex-grow: 0; + flex-shrink: 0; + font-size: 0; + height: 20px; + max-height: 20px; + max-width: 20px; + min-height: 20px; + min-width: 20px; + outline: none; + position: relative; + vertical-align: top; + width: 20px; +} + +.delete::before, .modal-close::before, .delete::after, .modal-close::after { + background-color: white; + content: ""; + display: block; + left: 50%; + position: absolute; + top: 50%; + -webkit-transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform: translateX(-50%) translateY(-50%) rotate(45deg); + -webkit-transform-origin: center center; + transform-origin: center center; +} + +.delete::before, .modal-close::before { + height: 2px; + width: 50%; +} + +.delete::after, .modal-close::after { + height: 50%; + width: 2px; +} + +.delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus { + background-color: rgba(10, 10, 10, 0.3); +} + +.delete:active, .modal-close:active { + background-color: rgba(10, 10, 10, 0.4); +} + +.is-small.delete, .is-small.modal-close { + height: 16px; + max-height: 16px; + max-width: 16px; + min-height: 16px; + min-width: 16px; + width: 16px; +} + +.is-medium.delete, .is-medium.modal-close { + height: 24px; + max-height: 24px; + max-width: 24px; + min-height: 24px; + min-width: 24px; + width: 24px; +} + +.is-large.delete, .is-large.modal-close { + height: 32px; + max-height: 32px; + max-width: 32px; + min-height: 32px; + min-width: 32px; + width: 32px; +} + +.button.is-loading::after, .loader, .select.is-loading::after, .control.is-loading::after { + -webkit-animation: spinAround 500ms infinite linear; + animation: spinAround 500ms infinite linear; + border: 2px solid #dbdbdb; + border-radius: 290486px; + border-right-color: transparent; + border-top-color: transparent; + content: ""; + display: block; + height: 1em; + position: relative; + width: 1em; +} + +.is-overlay, .image.is-square img, +.image.is-square .has-ratio, .image.is-1by1 img, +.image.is-1by1 .has-ratio, .image.is-5by4 img, +.image.is-5by4 .has-ratio, .image.is-4by3 img, +.image.is-4by3 .has-ratio, .image.is-3by2 img, +.image.is-3by2 .has-ratio, .image.is-5by3 img, +.image.is-5by3 .has-ratio, .image.is-16by9 img, +.image.is-16by9 .has-ratio, .image.is-2by1 img, +.image.is-2by1 .has-ratio, .image.is-3by1 img, +.image.is-3by1 .has-ratio, .image.is-4by5 img, +.image.is-4by5 .has-ratio, .image.is-3by4 img, +.image.is-3by4 .has-ratio, .image.is-2by3 img, +.image.is-2by3 .has-ratio, .image.is-3by5 img, +.image.is-3by5 .has-ratio, .image.is-9by16 img, +.image.is-9by16 .has-ratio, .image.is-1by2 img, +.image.is-1by2 .has-ratio, .image.is-1by3 img, +.image.is-1by3 .has-ratio, .modal, .modal-background, .hero-video { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.button, .input, .textarea, .select select, .file-cta, +.file-name, .pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis { + -moz-appearance: none; + -webkit-appearance: none; + align-items: center; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: none; + display: inline-flex; + font-size: 1rem; + height: 2.25em; + justify-content: flex-start; + line-height: 1.5; + padding-bottom: calc(0.375em - 1px); + padding-left: calc(0.625em - 1px); + padding-right: calc(0.625em - 1px); + padding-top: calc(0.375em - 1px); + position: relative; + vertical-align: top; +} + +.button:focus, .input:focus, .textarea:focus, .select select:focus, .file-cta:focus, +.file-name:focus, .pagination-previous:focus, +.pagination-next:focus, +.pagination-link:focus, +.pagination-ellipsis:focus, .is-focused.button, .is-focused.input, .is-focused.textarea, .select select.is-focused, .is-focused.file-cta, +.is-focused.file-name, .is-focused.pagination-previous, +.is-focused.pagination-next, +.is-focused.pagination-link, +.is-focused.pagination-ellipsis, .button:active, .input:active, .textarea:active, .select select:active, .file-cta:active, +.file-name:active, .pagination-previous:active, +.pagination-next:active, +.pagination-link:active, +.pagination-ellipsis:active, .is-active.button, .is-active.input, .is-active.textarea, .select select.is-active, .is-active.file-cta, +.is-active.file-name, .is-active.pagination-previous, +.is-active.pagination-next, +.is-active.pagination-link, +.is-active.pagination-ellipsis { + outline: none; +} + +.button[disabled], .input[disabled], .textarea[disabled], .select select[disabled], .file-cta[disabled], +.file-name[disabled], .pagination-previous[disabled], +.pagination-next[disabled], +.pagination-link[disabled], +.pagination-ellipsis[disabled], +fieldset[disabled] .button, +fieldset[disabled] .input, +fieldset[disabled] .textarea, +fieldset[disabled] .select select, +.select fieldset[disabled] select, +fieldset[disabled] .file-cta, +fieldset[disabled] .file-name, +fieldset[disabled] .pagination-previous, +fieldset[disabled] .pagination-next, +fieldset[disabled] .pagination-link, +fieldset[disabled] .pagination-ellipsis { + cursor: not-allowed; +} + +/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */ +html, +body, +p, +ol, +ul, +li, +dl, +dt, +dd, +blockquote, +figure, +fieldset, +legend, +textarea, +pre, +iframe, +hr, +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: 100%; + font-weight: normal; +} + +ul { + list-style: none; +} + +button, +input, +select, +textarea { + margin: 0; +} + +html { + box-sizing: border-box; +} + +*, *::before, *::after { + box-sizing: inherit; +} + +img, +embed, +iframe, +object, +video { + height: auto; + max-width: 100%; +} + +audio { + max-width: 100%; +} + +iframe { + border: 0; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +td:not([align]), +th:not([align]) { + text-align: left; +} + +html { + background-color: white; + font-size: 16px; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + min-width: 300px; + overflow-x: hidden; + overflow-y: scroll; + text-rendering: optimizeLegibility; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + text-size-adjust: 100%; +} + +article, +aside, +figure, +footer, +header, +hgroup, +section { + display: block; +} + +body, +button, +input, +select, +textarea { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif; +} + +code, +pre { + -moz-osx-font-smoothing: auto; + -webkit-font-smoothing: auto; + font-family: monospace; +} + +body { + color: #4a4a4a; + font-size: 1em; + font-weight: 400; + line-height: 1.5; +} + +a { + color: #3273dc; + cursor: pointer; + text-decoration: none; +} + +a strong { + color: currentColor; +} + +a:hover { + color: #363636; +} + +code { + background-color: whitesmoke; + color: #ff3860; + font-size: 0.875em; + font-weight: normal; + padding: 0.25em 0.5em 0.25em; +} + +hr { + background-color: whitesmoke; + border: none; + display: block; + height: 2px; + margin: 1.5rem 0; +} + +img { + height: auto; + max-width: 100%; +} + +input[type="checkbox"], +input[type="radio"] { + vertical-align: baseline; +} + +small { + font-size: 0.875em; +} + +span { + font-style: inherit; + font-weight: inherit; +} + +strong { + color: #363636; + font-weight: 700; +} + +fieldset { + border: none; +} + +pre { + -webkit-overflow-scrolling: touch; + background-color: whitesmoke; + color: #4a4a4a; + font-size: 0.875em; + overflow-x: auto; + padding: 1.25rem 1.5rem; + white-space: pre; + word-wrap: normal; +} + +pre code { + background-color: transparent; + color: currentColor; + font-size: 1em; + padding: 0; +} + +table td, +table th { + vertical-align: top; +} + +table td:not([align]), +table th:not([align]) { + text-align: left; +} + +table th { + color: #363636; +} + +.is-clearfix::after { + clear: both; + content: " "; + display: table; +} + +.is-pulled-left { + float: left !important; +} + +.is-pulled-right { + float: right !important; +} + +.is-clipped { + overflow: hidden !important; +} + +.is-size-1 { + font-size: 3rem !important; +} + +.is-size-2 { + font-size: 2.5rem !important; +} + +.is-size-3 { + font-size: 2rem !important; +} + +.is-size-4 { + font-size: 1.5rem !important; +} + +.is-size-5 { + font-size: 1.25rem !important; +} + +.is-size-6 { + font-size: 1rem !important; +} + +.is-size-7 { + font-size: 0.75rem !important; +} + +@media screen and (max-width: 768px) { + .is-size-1-mobile { + font-size: 3rem !important; + } + .is-size-2-mobile { + font-size: 2.5rem !important; + } + .is-size-3-mobile { + font-size: 2rem !important; + } + .is-size-4-mobile { + font-size: 1.5rem !important; + } + .is-size-5-mobile { + font-size: 1.25rem !important; + } + .is-size-6-mobile { + font-size: 1rem !important; + } + .is-size-7-mobile { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 769px), print { + .is-size-1-tablet { + font-size: 3rem !important; + } + .is-size-2-tablet { + font-size: 2.5rem !important; + } + .is-size-3-tablet { + font-size: 2rem !important; + } + .is-size-4-tablet { + font-size: 1.5rem !important; + } + .is-size-5-tablet { + font-size: 1.25rem !important; + } + .is-size-6-tablet { + font-size: 1rem !important; + } + .is-size-7-tablet { + font-size: 0.75rem !important; + } +} + +@media screen and (max-width: 1023px) { + .is-size-1-touch { + font-size: 3rem !important; + } + .is-size-2-touch { + font-size: 2.5rem !important; + } + .is-size-3-touch { + font-size: 2rem !important; + } + .is-size-4-touch { + font-size: 1.5rem !important; + } + .is-size-5-touch { + font-size: 1.25rem !important; + } + .is-size-6-touch { + font-size: 1rem !important; + } + .is-size-7-touch { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1024px) { + .is-size-1-desktop { + font-size: 3rem !important; + } + .is-size-2-desktop { + font-size: 2.5rem !important; + } + .is-size-3-desktop { + font-size: 2rem !important; + } + .is-size-4-desktop { + font-size: 1.5rem !important; + } + .is-size-5-desktop { + font-size: 1.25rem !important; + } + .is-size-6-desktop { + font-size: 1rem !important; + } + .is-size-7-desktop { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1216px) { + .is-size-1-widescreen { + font-size: 3rem !important; + } + .is-size-2-widescreen { + font-size: 2.5rem !important; + } + .is-size-3-widescreen { + font-size: 2rem !important; + } + .is-size-4-widescreen { + font-size: 1.5rem !important; + } + .is-size-5-widescreen { + font-size: 1.25rem !important; + } + .is-size-6-widescreen { + font-size: 1rem !important; + } + .is-size-7-widescreen { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1408px) { + .is-size-1-fullhd { + font-size: 3rem !important; + } + .is-size-2-fullhd { + font-size: 2.5rem !important; + } + .is-size-3-fullhd { + font-size: 2rem !important; + } + .is-size-4-fullhd { + font-size: 1.5rem !important; + } + .is-size-5-fullhd { + font-size: 1.25rem !important; + } + .is-size-6-fullhd { + font-size: 1rem !important; + } + .is-size-7-fullhd { + font-size: 0.75rem !important; + } +} + +.has-text-centered { + text-align: center !important; +} + +.has-text-justified { + text-align: justify !important; +} + +.has-text-left { + text-align: left !important; +} + +.has-text-right { + text-align: right !important; +} + +@media screen and (max-width: 768px) { + .has-text-centered-mobile { + text-align: center !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-centered-tablet { + text-align: center !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-centered-tablet-only { + text-align: center !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-centered-touch { + text-align: center !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-centered-desktop { + text-align: center !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-centered-desktop-only { + text-align: center !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-centered-widescreen { + text-align: center !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-centered-widescreen-only { + text-align: center !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-centered-fullhd { + text-align: center !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-justified-mobile { + text-align: justify !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-justified-tablet { + text-align: justify !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-justified-tablet-only { + text-align: justify !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-justified-touch { + text-align: justify !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-justified-desktop { + text-align: justify !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-justified-desktop-only { + text-align: justify !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-justified-widescreen { + text-align: justify !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-justified-widescreen-only { + text-align: justify !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-justified-fullhd { + text-align: justify !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-left-mobile { + text-align: left !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-left-tablet { + text-align: left !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-left-tablet-only { + text-align: left !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-left-touch { + text-align: left !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-left-desktop { + text-align: left !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-left-desktop-only { + text-align: left !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-left-widescreen { + text-align: left !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-left-widescreen-only { + text-align: left !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-left-fullhd { + text-align: left !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-right-mobile { + text-align: right !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-right-tablet { + text-align: right !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-right-tablet-only { + text-align: right !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-right-touch { + text-align: right !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-right-desktop { + text-align: right !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-right-desktop-only { + text-align: right !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-right-widescreen { + text-align: right !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-right-widescreen-only { + text-align: right !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-right-fullhd { + text-align: right !important; + } +} + +.is-capitalized { + text-transform: capitalize !important; +} + +.is-lowercase { + text-transform: lowercase !important; +} + +.is-uppercase { + text-transform: uppercase !important; +} + +.is-italic { + font-style: italic !important; +} + +.has-text-white { + color: white !important; +} + +a.has-text-white:hover, a.has-text-white:focus { + color: #e6e6e6 !important; +} + +.has-background-white { + background-color: white !important; +} + +.has-text-black { + color: #0a0a0a !important; +} + +a.has-text-black:hover, a.has-text-black:focus { + color: black !important; +} + +.has-background-black { + background-color: #0a0a0a !important; +} + +.has-text-light { + color: whitesmoke !important; +} + +a.has-text-light:hover, a.has-text-light:focus { + color: #dbdbdb !important; +} + +.has-background-light { + background-color: whitesmoke !important; +} + +.has-text-dark { + color: #363636 !important; +} + +a.has-text-dark:hover, a.has-text-dark:focus { + color: #1c1c1c !important; +} + +.has-background-dark { + background-color: #363636 !important; +} + +.has-text-primary { + color: #00d1b2 !important; +} + +a.has-text-primary:hover, a.has-text-primary:focus { + color: #009e86 !important; +} + +.has-background-primary { + background-color: #00d1b2 !important; +} + +.has-text-link { + color: #3273dc !important; +} + +a.has-text-link:hover, a.has-text-link:focus { + color: #205bbc !important; +} + +.has-background-link { + background-color: #3273dc !important; +} + +.has-text-info { + color: #209cee !important; +} + +a.has-text-info:hover, a.has-text-info:focus { + color: #0f81cc !important; +} + +.has-background-info { + background-color: #209cee !important; +} + +.has-text-success { + color: #23d160 !important; +} + +a.has-text-success:hover, a.has-text-success:focus { + color: #1ca64c !important; +} + +.has-background-success { + background-color: #23d160 !important; +} + +.has-text-warning { + color: #ffdd57 !important; +} + +a.has-text-warning:hover, a.has-text-warning:focus { + color: #ffd324 !important; +} + +.has-background-warning { + background-color: #ffdd57 !important; +} + +.has-text-danger { + color: #ff3860 !important; +} + +a.has-text-danger:hover, a.has-text-danger:focus { + color: #ff0537 !important; +} + +.has-background-danger { + background-color: #ff3860 !important; +} + +.has-text-black-bis { + color: #121212 !important; +} + +.has-background-black-bis { + background-color: #121212 !important; +} + +.has-text-black-ter { + color: #242424 !important; +} + +.has-background-black-ter { + background-color: #242424 !important; +} + +.has-text-grey-darker { + color: #363636 !important; +} + +.has-background-grey-darker { + background-color: #363636 !important; +} + +.has-text-grey-dark { + color: #4a4a4a !important; +} + +.has-background-grey-dark { + background-color: #4a4a4a !important; +} + +.has-text-grey { + color: #7a7a7a !important; +} + +.has-background-grey { + background-color: #7a7a7a !important; +} + +.has-text-grey-light { + color: #b5b5b5 !important; +} + +.has-background-grey-light { + background-color: #b5b5b5 !important; +} + +.has-text-grey-lighter { + color: #dbdbdb !important; +} + +.has-background-grey-lighter { + background-color: #dbdbdb !important; +} + +.has-text-white-ter { + color: whitesmoke !important; +} + +.has-background-white-ter { + background-color: whitesmoke !important; +} + +.has-text-white-bis { + color: #fafafa !important; +} + +.has-background-white-bis { + background-color: #fafafa !important; +} + +.has-text-weight-light { + font-weight: 300 !important; +} + +.has-text-weight-normal { + font-weight: 400 !important; +} + +.has-text-weight-medium { + font-weight: 500 !important; +} + +.has-text-weight-semibold { + font-weight: 600 !important; +} + +.has-text-weight-bold { + font-weight: 700 !important; +} + +.is-family-primary { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-secondary { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-sans-serif { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-monospace { + font-family: monospace !important; +} + +.is-family-code { + font-family: monospace !important; +} + +.is-block { + display: block !important; +} + +@media screen and (max-width: 768px) { + .is-block-mobile { + display: block !important; + } +} + +@media screen and (min-width: 769px), print { + .is-block-tablet { + display: block !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-block-tablet-only { + display: block !important; + } +} + +@media screen and (max-width: 1023px) { + .is-block-touch { + display: block !important; + } +} + +@media screen and (min-width: 1024px) { + .is-block-desktop { + display: block !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-block-desktop-only { + display: block !important; + } +} + +@media screen and (min-width: 1216px) { + .is-block-widescreen { + display: block !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-block-widescreen-only { + display: block !important; + } +} + +@media screen and (min-width: 1408px) { + .is-block-fullhd { + display: block !important; + } +} + +.is-flex { + display: flex !important; +} + +@media screen and (max-width: 768px) { + .is-flex-mobile { + display: flex !important; + } +} + +@media screen and (min-width: 769px), print { + .is-flex-tablet { + display: flex !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-flex-tablet-only { + display: flex !important; + } +} + +@media screen and (max-width: 1023px) { + .is-flex-touch { + display: flex !important; + } +} + +@media screen and (min-width: 1024px) { + .is-flex-desktop { + display: flex !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-flex-desktop-only { + display: flex !important; + } +} + +@media screen and (min-width: 1216px) { + .is-flex-widescreen { + display: flex !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-flex-widescreen-only { + display: flex !important; + } +} + +@media screen and (min-width: 1408px) { + .is-flex-fullhd { + display: flex !important; + } +} + +.is-inline { + display: inline !important; +} + +@media screen and (max-width: 768px) { + .is-inline-mobile { + display: inline !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-tablet { + display: inline !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-tablet-only { + display: inline !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-touch { + display: inline !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-desktop { + display: inline !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-desktop-only { + display: inline !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-widescreen { + display: inline !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-widescreen-only { + display: inline !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-fullhd { + display: inline !important; + } +} + +.is-inline-block { + display: inline-block !important; +} + +@media screen and (max-width: 768px) { + .is-inline-block-mobile { + display: inline-block !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-block-tablet { + display: inline-block !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-block-tablet-only { + display: inline-block !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-block-touch { + display: inline-block !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-block-desktop { + display: inline-block !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-block-desktop-only { + display: inline-block !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-block-widescreen { + display: inline-block !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-block-widescreen-only { + display: inline-block !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-block-fullhd { + display: inline-block !important; + } +} + +.is-inline-flex { + display: inline-flex !important; +} + +@media screen and (max-width: 768px) { + .is-inline-flex-mobile { + display: inline-flex !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-flex-tablet { + display: inline-flex !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-flex-tablet-only { + display: inline-flex !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-flex-touch { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-flex-desktop { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-flex-desktop-only { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-flex-widescreen { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-flex-widescreen-only { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-flex-fullhd { + display: inline-flex !important; + } +} + +.is-hidden { + display: none !important; +} + +.is-sr-only { + border: none !important; + clip: rect(0, 0, 0, 0) !important; + height: 0.01em !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + white-space: nowrap !important; + width: 0.01em !important; +} + +@media screen and (max-width: 768px) { + .is-hidden-mobile { + display: none !important; + } +} + +@media screen and (min-width: 769px), print { + .is-hidden-tablet { + display: none !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-hidden-tablet-only { + display: none !important; + } +} + +@media screen and (max-width: 1023px) { + .is-hidden-touch { + display: none !important; + } +} + +@media screen and (min-width: 1024px) { + .is-hidden-desktop { + display: none !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-hidden-desktop-only { + display: none !important; + } +} + +@media screen and (min-width: 1216px) { + .is-hidden-widescreen { + display: none !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-hidden-widescreen-only { + display: none !important; + } +} + +@media screen and (min-width: 1408px) { + .is-hidden-fullhd { + display: none !important; + } +} + +.is-invisible { + visibility: hidden !important; +} + +@media screen and (max-width: 768px) { + .is-invisible-mobile { + visibility: hidden !important; + } +} + +@media screen and (min-width: 769px), print { + .is-invisible-tablet { + visibility: hidden !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-invisible-tablet-only { + visibility: hidden !important; + } +} + +@media screen and (max-width: 1023px) { + .is-invisible-touch { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1024px) { + .is-invisible-desktop { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-invisible-desktop-only { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1216px) { + .is-invisible-widescreen { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-invisible-widescreen-only { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1408px) { + .is-invisible-fullhd { + visibility: hidden !important; + } +} + +.is-marginless { + margin: 0 !important; +} + +.is-paddingless { + padding: 0 !important; +} + +.is-radiusless { + border-radius: 0 !important; +} + +.is-shadowless { + box-shadow: none !important; +} + +.is-relative { + position: relative !important; +} + +.box { + background-color: white; + border-radius: 6px; + box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); + color: #4a4a4a; + display: block; + padding: 1.25rem; +} + +a.box:hover, a.box:focus { + box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px #3273dc; +} + +a.box:active { + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2), 0 0 0 1px #3273dc; +} + +.button { + background-color: white; + border-color: #dbdbdb; + border-width: 1px; + color: #363636; + cursor: pointer; + justify-content: center; + padding-bottom: calc(0.375em - 1px); + padding-left: 0.75em; + padding-right: 0.75em; + padding-top: calc(0.375em - 1px); + text-align: center; + white-space: nowrap; +} + +.button strong { + color: inherit; +} + +.button .icon, .button .icon.is-small, .button .icon.is-medium, .button .icon.is-large { + height: 1.5em; + width: 1.5em; +} + +.button .icon:first-child:not(:last-child) { + margin-left: calc(-0.375em - 1px); + margin-right: 0.1875em; +} + +.button .icon:last-child:not(:first-child) { + margin-left: 0.1875em; + margin-right: calc(-0.375em - 1px); +} + +.button .icon:first-child:last-child { + margin-left: calc(-0.375em - 1px); + margin-right: calc(-0.375em - 1px); +} + +.button:hover, .button.is-hovered { + border-color: #b5b5b5; + color: #363636; +} + +.button:focus, .button.is-focused { + border-color: #3273dc; + color: #363636; +} + +.button:focus:not(:active), .button.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.button:active, .button.is-active { + border-color: #4a4a4a; + color: #363636; +} + +.button.is-text { + background-color: transparent; + border-color: transparent; + color: #4a4a4a; + text-decoration: underline; +} + +.button.is-text:hover, .button.is-text.is-hovered, .button.is-text:focus, .button.is-text.is-focused { + background-color: whitesmoke; + color: #363636; +} + +.button.is-text:active, .button.is-text.is-active { + background-color: #e8e8e8; + color: #363636; +} + +.button.is-text[disabled], +fieldset[disabled] .button.is-text { + background-color: transparent; + border-color: transparent; + box-shadow: none; +} + +.button.is-white { + background-color: white; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:hover, .button.is-white.is-hovered { + background-color: #f9f9f9; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:focus, .button.is-white.is-focused { + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:focus:not(:active), .button.is-white.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.button.is-white:active, .button.is-white.is-active { + background-color: #f2f2f2; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white[disabled], +fieldset[disabled] .button.is-white { + background-color: white; + border-color: transparent; + box-shadow: none; +} + +.button.is-white.is-inverted { + background-color: #0a0a0a; + color: white; +} + +.button.is-white.is-inverted:hover, .button.is-white.is-inverted.is-hovered { + background-color: black; +} + +.button.is-white.is-inverted[disabled], +fieldset[disabled] .button.is-white.is-inverted { + background-color: #0a0a0a; + border-color: transparent; + box-shadow: none; + color: white; +} + +.button.is-white.is-loading::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-white.is-outlined { + background-color: transparent; + border-color: white; + color: white; +} + +.button.is-white.is-outlined:hover, .button.is-white.is-outlined.is-hovered, .button.is-white.is-outlined:focus, .button.is-white.is-outlined.is-focused { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.button.is-white.is-outlined.is-loading::after { + border-color: transparent transparent white white !important; +} + +.button.is-white.is-outlined.is-loading:hover::after, .button.is-white.is-outlined.is-loading.is-hovered::after, .button.is-white.is-outlined.is-loading:focus::after, .button.is-white.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-white.is-outlined[disabled], +fieldset[disabled] .button.is-white.is-outlined { + background-color: transparent; + border-color: white; + box-shadow: none; + color: white; +} + +.button.is-white.is-inverted.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + color: #0a0a0a; +} + +.button.is-white.is-inverted.is-outlined:hover, .button.is-white.is-inverted.is-outlined.is-hovered, .button.is-white.is-inverted.is-outlined:focus, .button.is-white.is-inverted.is-outlined.is-focused { + background-color: #0a0a0a; + color: white; +} + +.button.is-white.is-inverted.is-outlined.is-loading:hover::after, .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-white.is-inverted.is-outlined.is-loading:focus::after, .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent white white !important; +} + +.button.is-white.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-white.is-inverted.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black { + background-color: #0a0a0a; + border-color: transparent; + color: white; +} + +.button.is-black:hover, .button.is-black.is-hovered { + background-color: #040404; + border-color: transparent; + color: white; +} + +.button.is-black:focus, .button.is-black.is-focused { + border-color: transparent; + color: white; +} + +.button.is-black:focus:not(:active), .button.is-black.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.button.is-black:active, .button.is-black.is-active { + background-color: black; + border-color: transparent; + color: white; +} + +.button.is-black[disabled], +fieldset[disabled] .button.is-black { + background-color: #0a0a0a; + border-color: transparent; + box-shadow: none; +} + +.button.is-black.is-inverted { + background-color: white; + color: #0a0a0a; +} + +.button.is-black.is-inverted:hover, .button.is-black.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-black.is-inverted[disabled], +fieldset[disabled] .button.is-black.is-inverted { + background-color: white; + border-color: transparent; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black.is-loading::after { + border-color: transparent transparent white white !important; +} + +.button.is-black.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + color: #0a0a0a; +} + +.button.is-black.is-outlined:hover, .button.is-black.is-outlined.is-hovered, .button.is-black.is-outlined:focus, .button.is-black.is-outlined.is-focused { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.button.is-black.is-outlined.is-loading::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-black.is-outlined.is-loading:hover::after, .button.is-black.is-outlined.is-loading.is-hovered::after, .button.is-black.is-outlined.is-loading:focus::after, .button.is-black.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent white white !important; +} + +.button.is-black.is-outlined[disabled], +fieldset[disabled] .button.is-black.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black.is-inverted.is-outlined { + background-color: transparent; + border-color: white; + color: white; +} + +.button.is-black.is-inverted.is-outlined:hover, .button.is-black.is-inverted.is-outlined.is-hovered, .button.is-black.is-inverted.is-outlined:focus, .button.is-black.is-inverted.is-outlined.is-focused { + background-color: white; + color: #0a0a0a; +} + +.button.is-black.is-inverted.is-outlined.is-loading:hover::after, .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-black.is-inverted.is-outlined.is-loading:focus::after, .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-black.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-black.is-inverted.is-outlined { + background-color: transparent; + border-color: white; + box-shadow: none; + color: white; +} + +.button.is-light { + background-color: whitesmoke; + border-color: transparent; + color: #363636; +} + +.button.is-light:hover, .button.is-light.is-hovered { + background-color: #eeeeee; + border-color: transparent; + color: #363636; +} + +.button.is-light:focus, .button.is-light.is-focused { + border-color: transparent; + color: #363636; +} + +.button.is-light:focus:not(:active), .button.is-light.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.button.is-light:active, .button.is-light.is-active { + background-color: #e8e8e8; + border-color: transparent; + color: #363636; +} + +.button.is-light[disabled], +fieldset[disabled] .button.is-light { + background-color: whitesmoke; + border-color: transparent; + box-shadow: none; +} + +.button.is-light.is-inverted { + background-color: #363636; + color: whitesmoke; +} + +.button.is-light.is-inverted:hover, .button.is-light.is-inverted.is-hovered { + background-color: #292929; +} + +.button.is-light.is-inverted[disabled], +fieldset[disabled] .button.is-light.is-inverted { + background-color: #363636; + border-color: transparent; + box-shadow: none; + color: whitesmoke; +} + +.button.is-light.is-loading::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-light.is-outlined { + background-color: transparent; + border-color: whitesmoke; + color: whitesmoke; +} + +.button.is-light.is-outlined:hover, .button.is-light.is-outlined.is-hovered, .button.is-light.is-outlined:focus, .button.is-light.is-outlined.is-focused { + background-color: whitesmoke; + border-color: whitesmoke; + color: #363636; +} + +.button.is-light.is-outlined.is-loading::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-light.is-outlined.is-loading:hover::after, .button.is-light.is-outlined.is-loading.is-hovered::after, .button.is-light.is-outlined.is-loading:focus::after, .button.is-light.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-light.is-outlined[disabled], +fieldset[disabled] .button.is-light.is-outlined { + background-color: transparent; + border-color: whitesmoke; + box-shadow: none; + color: whitesmoke; +} + +.button.is-light.is-inverted.is-outlined { + background-color: transparent; + border-color: #363636; + color: #363636; +} + +.button.is-light.is-inverted.is-outlined:hover, .button.is-light.is-inverted.is-outlined.is-hovered, .button.is-light.is-inverted.is-outlined:focus, .button.is-light.is-inverted.is-outlined.is-focused { + background-color: #363636; + color: whitesmoke; +} + +.button.is-light.is-inverted.is-outlined.is-loading:hover::after, .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-light.is-inverted.is-outlined.is-loading:focus::after, .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-light.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-light.is-inverted.is-outlined { + background-color: transparent; + border-color: #363636; + box-shadow: none; + color: #363636; +} + +.button.is-dark { + background-color: #363636; + border-color: transparent; + color: whitesmoke; +} + +.button.is-dark:hover, .button.is-dark.is-hovered { + background-color: #2f2f2f; + border-color: transparent; + color: whitesmoke; +} + +.button.is-dark:focus, .button.is-dark.is-focused { + border-color: transparent; + color: whitesmoke; +} + +.button.is-dark:focus:not(:active), .button.is-dark.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.button.is-dark:active, .button.is-dark.is-active { + background-color: #292929; + border-color: transparent; + color: whitesmoke; +} + +.button.is-dark[disabled], +fieldset[disabled] .button.is-dark { + background-color: #363636; + border-color: transparent; + box-shadow: none; +} + +.button.is-dark.is-inverted { + background-color: whitesmoke; + color: #363636; +} + +.button.is-dark.is-inverted:hover, .button.is-dark.is-inverted.is-hovered { + background-color: #e8e8e8; +} + +.button.is-dark.is-inverted[disabled], +fieldset[disabled] .button.is-dark.is-inverted { + background-color: whitesmoke; + border-color: transparent; + box-shadow: none; + color: #363636; +} + +.button.is-dark.is-loading::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-dark.is-outlined { + background-color: transparent; + border-color: #363636; + color: #363636; +} + +.button.is-dark.is-outlined:hover, .button.is-dark.is-outlined.is-hovered, .button.is-dark.is-outlined:focus, .button.is-dark.is-outlined.is-focused { + background-color: #363636; + border-color: #363636; + color: whitesmoke; +} + +.button.is-dark.is-outlined.is-loading::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-dark.is-outlined.is-loading:hover::after, .button.is-dark.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-outlined.is-loading:focus::after, .button.is-dark.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-dark.is-outlined[disabled], +fieldset[disabled] .button.is-dark.is-outlined { + background-color: transparent; + border-color: #363636; + box-shadow: none; + color: #363636; +} + +.button.is-dark.is-inverted.is-outlined { + background-color: transparent; + border-color: whitesmoke; + color: whitesmoke; +} + +.button.is-dark.is-inverted.is-outlined:hover, .button.is-dark.is-inverted.is-outlined.is-hovered, .button.is-dark.is-inverted.is-outlined:focus, .button.is-dark.is-inverted.is-outlined.is-focused { + background-color: whitesmoke; + color: #363636; +} + +.button.is-dark.is-inverted.is-outlined.is-loading:hover::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-inverted.is-outlined.is-loading:focus::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-dark.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-dark.is-inverted.is-outlined { + background-color: transparent; + border-color: whitesmoke; + box-shadow: none; + color: whitesmoke; +} + +.button.is-primary { + background-color: #00d1b2; + border-color: transparent; + color: #fff; +} + +.button.is-primary:hover, .button.is-primary.is-hovered { + background-color: #00c4a7; + border-color: transparent; + color: #fff; +} + +.button.is-primary:focus, .button.is-primary.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-primary:focus:not(:active), .button.is-primary.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.button.is-primary:active, .button.is-primary.is-active { + background-color: #00b89c; + border-color: transparent; + color: #fff; +} + +.button.is-primary[disabled], +fieldset[disabled] .button.is-primary { + background-color: #00d1b2; + border-color: transparent; + box-shadow: none; +} + +.button.is-primary.is-inverted { + background-color: #fff; + color: #00d1b2; +} + +.button.is-primary.is-inverted:hover, .button.is-primary.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-primary.is-inverted[disabled], +fieldset[disabled] .button.is-primary.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #00d1b2; +} + +.button.is-primary.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-primary.is-outlined { + background-color: transparent; + border-color: #00d1b2; + color: #00d1b2; +} + +.button.is-primary.is-outlined:hover, .button.is-primary.is-outlined.is-hovered, .button.is-primary.is-outlined:focus, .button.is-primary.is-outlined.is-focused { + background-color: #00d1b2; + border-color: #00d1b2; + color: #fff; +} + +.button.is-primary.is-outlined.is-loading::after { + border-color: transparent transparent #00d1b2 #00d1b2 !important; +} + +.button.is-primary.is-outlined.is-loading:hover::after, .button.is-primary.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-outlined.is-loading:focus::after, .button.is-primary.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-primary.is-outlined[disabled], +fieldset[disabled] .button.is-primary.is-outlined { + background-color: transparent; + border-color: #00d1b2; + box-shadow: none; + color: #00d1b2; +} + +.button.is-primary.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-primary.is-inverted.is-outlined:hover, .button.is-primary.is-inverted.is-outlined.is-hovered, .button.is-primary.is-inverted.is-outlined:focus, .button.is-primary.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #00d1b2; +} + +.button.is-primary.is-inverted.is-outlined.is-loading:hover::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-inverted.is-outlined.is-loading:focus::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #00d1b2 #00d1b2 !important; +} + +.button.is-primary.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-primary.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-link { + background-color: #3273dc; + border-color: transparent; + color: #fff; +} + +.button.is-link:hover, .button.is-link.is-hovered { + background-color: #276cda; + border-color: transparent; + color: #fff; +} + +.button.is-link:focus, .button.is-link.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-link:focus:not(:active), .button.is-link.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.button.is-link:active, .button.is-link.is-active { + background-color: #2366d1; + border-color: transparent; + color: #fff; +} + +.button.is-link[disabled], +fieldset[disabled] .button.is-link { + background-color: #3273dc; + border-color: transparent; + box-shadow: none; +} + +.button.is-link.is-inverted { + background-color: #fff; + color: #3273dc; +} + +.button.is-link.is-inverted:hover, .button.is-link.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-link.is-inverted[disabled], +fieldset[disabled] .button.is-link.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #3273dc; +} + +.button.is-link.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-link.is-outlined { + background-color: transparent; + border-color: #3273dc; + color: #3273dc; +} + +.button.is-link.is-outlined:hover, .button.is-link.is-outlined.is-hovered, .button.is-link.is-outlined:focus, .button.is-link.is-outlined.is-focused { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.button.is-link.is-outlined.is-loading::after { + border-color: transparent transparent #3273dc #3273dc !important; +} + +.button.is-link.is-outlined.is-loading:hover::after, .button.is-link.is-outlined.is-loading.is-hovered::after, .button.is-link.is-outlined.is-loading:focus::after, .button.is-link.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-link.is-outlined[disabled], +fieldset[disabled] .button.is-link.is-outlined { + background-color: transparent; + border-color: #3273dc; + box-shadow: none; + color: #3273dc; +} + +.button.is-link.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-link.is-inverted.is-outlined:hover, .button.is-link.is-inverted.is-outlined.is-hovered, .button.is-link.is-inverted.is-outlined:focus, .button.is-link.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #3273dc; +} + +.button.is-link.is-inverted.is-outlined.is-loading:hover::after, .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-link.is-inverted.is-outlined.is-loading:focus::after, .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #3273dc #3273dc !important; +} + +.button.is-link.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-link.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-info { + background-color: #209cee; + border-color: transparent; + color: #fff; +} + +.button.is-info:hover, .button.is-info.is-hovered { + background-color: #1496ed; + border-color: transparent; + color: #fff; +} + +.button.is-info:focus, .button.is-info.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-info:focus:not(:active), .button.is-info.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(32, 156, 238, 0.25); +} + +.button.is-info:active, .button.is-info.is-active { + background-color: #118fe4; + border-color: transparent; + color: #fff; +} + +.button.is-info[disabled], +fieldset[disabled] .button.is-info { + background-color: #209cee; + border-color: transparent; + box-shadow: none; +} + +.button.is-info.is-inverted { + background-color: #fff; + color: #209cee; +} + +.button.is-info.is-inverted:hover, .button.is-info.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-info.is-inverted[disabled], +fieldset[disabled] .button.is-info.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #209cee; +} + +.button.is-info.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-info.is-outlined { + background-color: transparent; + border-color: #209cee; + color: #209cee; +} + +.button.is-info.is-outlined:hover, .button.is-info.is-outlined.is-hovered, .button.is-info.is-outlined:focus, .button.is-info.is-outlined.is-focused { + background-color: #209cee; + border-color: #209cee; + color: #fff; +} + +.button.is-info.is-outlined.is-loading::after { + border-color: transparent transparent #209cee #209cee !important; +} + +.button.is-info.is-outlined.is-loading:hover::after, .button.is-info.is-outlined.is-loading.is-hovered::after, .button.is-info.is-outlined.is-loading:focus::after, .button.is-info.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-info.is-outlined[disabled], +fieldset[disabled] .button.is-info.is-outlined { + background-color: transparent; + border-color: #209cee; + box-shadow: none; + color: #209cee; +} + +.button.is-info.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-info.is-inverted.is-outlined:hover, .button.is-info.is-inverted.is-outlined.is-hovered, .button.is-info.is-inverted.is-outlined:focus, .button.is-info.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #209cee; +} + +.button.is-info.is-inverted.is-outlined.is-loading:hover::after, .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-info.is-inverted.is-outlined.is-loading:focus::after, .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #209cee #209cee !important; +} + +.button.is-info.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-info.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-success { + background-color: #23d160; + border-color: transparent; + color: #fff; +} + +.button.is-success:hover, .button.is-success.is-hovered { + background-color: #22c65b; + border-color: transparent; + color: #fff; +} + +.button.is-success:focus, .button.is-success.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-success:focus:not(:active), .button.is-success.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(35, 209, 96, 0.25); +} + +.button.is-success:active, .button.is-success.is-active { + background-color: #20bc56; + border-color: transparent; + color: #fff; +} + +.button.is-success[disabled], +fieldset[disabled] .button.is-success { + background-color: #23d160; + border-color: transparent; + box-shadow: none; +} + +.button.is-success.is-inverted { + background-color: #fff; + color: #23d160; +} + +.button.is-success.is-inverted:hover, .button.is-success.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-success.is-inverted[disabled], +fieldset[disabled] .button.is-success.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #23d160; +} + +.button.is-success.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-success.is-outlined { + background-color: transparent; + border-color: #23d160; + color: #23d160; +} + +.button.is-success.is-outlined:hover, .button.is-success.is-outlined.is-hovered, .button.is-success.is-outlined:focus, .button.is-success.is-outlined.is-focused { + background-color: #23d160; + border-color: #23d160; + color: #fff; +} + +.button.is-success.is-outlined.is-loading::after { + border-color: transparent transparent #23d160 #23d160 !important; +} + +.button.is-success.is-outlined.is-loading:hover::after, .button.is-success.is-outlined.is-loading.is-hovered::after, .button.is-success.is-outlined.is-loading:focus::after, .button.is-success.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-success.is-outlined[disabled], +fieldset[disabled] .button.is-success.is-outlined { + background-color: transparent; + border-color: #23d160; + box-shadow: none; + color: #23d160; +} + +.button.is-success.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-success.is-inverted.is-outlined:hover, .button.is-success.is-inverted.is-outlined.is-hovered, .button.is-success.is-inverted.is-outlined:focus, .button.is-success.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #23d160; +} + +.button.is-success.is-inverted.is-outlined.is-loading:hover::after, .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-success.is-inverted.is-outlined.is-loading:focus::after, .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #23d160 #23d160 !important; +} + +.button.is-success.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-success.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-warning { + background-color: #ffdd57; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:hover, .button.is-warning.is-hovered { + background-color: #ffdb4a; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:focus, .button.is-warning.is-focused { + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:focus:not(:active), .button.is-warning.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.button.is-warning:active, .button.is-warning.is-active { + background-color: #ffd83d; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning[disabled], +fieldset[disabled] .button.is-warning { + background-color: #ffdd57; + border-color: transparent; + box-shadow: none; +} + +.button.is-warning.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.button.is-warning.is-inverted:hover, .button.is-warning.is-inverted.is-hovered { + background-color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-inverted[disabled], +fieldset[disabled] .button.is-warning.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + border-color: transparent; + box-shadow: none; + color: #ffdd57; +} + +.button.is-warning.is-loading::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-warning.is-outlined { + background-color: transparent; + border-color: #ffdd57; + color: #ffdd57; +} + +.button.is-warning.is-outlined:hover, .button.is-warning.is-outlined.is-hovered, .button.is-warning.is-outlined:focus, .button.is-warning.is-outlined.is-focused { + background-color: #ffdd57; + border-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-outlined.is-loading::after { + border-color: transparent transparent #ffdd57 #ffdd57 !important; +} + +.button.is-warning.is-outlined.is-loading:hover::after, .button.is-warning.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-outlined.is-loading:focus::after, .button.is-warning.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-warning.is-outlined[disabled], +fieldset[disabled] .button.is-warning.is-outlined { + background-color: transparent; + border-color: #ffdd57; + box-shadow: none; + color: #ffdd57; +} + +.button.is-warning.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-inverted.is-outlined:hover, .button.is-warning.is-inverted.is-outlined.is-hovered, .button.is-warning.is-inverted.is-outlined:focus, .button.is-warning.is-inverted.is-outlined.is-focused { + background-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.button.is-warning.is-inverted.is-outlined.is-loading:hover::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-inverted.is-outlined.is-loading:focus::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #ffdd57 #ffdd57 !important; +} + +.button.is-warning.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-warning.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + box-shadow: none; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-danger { + background-color: #ff3860; + border-color: transparent; + color: #fff; +} + +.button.is-danger:hover, .button.is-danger.is-hovered { + background-color: #ff2b56; + border-color: transparent; + color: #fff; +} + +.button.is-danger:focus, .button.is-danger.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-danger:focus:not(:active), .button.is-danger.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(255, 56, 96, 0.25); +} + +.button.is-danger:active, .button.is-danger.is-active { + background-color: #ff1f4b; + border-color: transparent; + color: #fff; +} + +.button.is-danger[disabled], +fieldset[disabled] .button.is-danger { + background-color: #ff3860; + border-color: transparent; + box-shadow: none; +} + +.button.is-danger.is-inverted { + background-color: #fff; + color: #ff3860; +} + +.button.is-danger.is-inverted:hover, .button.is-danger.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-danger.is-inverted[disabled], +fieldset[disabled] .button.is-danger.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #ff3860; +} + +.button.is-danger.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-danger.is-outlined { + background-color: transparent; + border-color: #ff3860; + color: #ff3860; +} + +.button.is-danger.is-outlined:hover, .button.is-danger.is-outlined.is-hovered, .button.is-danger.is-outlined:focus, .button.is-danger.is-outlined.is-focused { + background-color: #ff3860; + border-color: #ff3860; + color: #fff; +} + +.button.is-danger.is-outlined.is-loading::after { + border-color: transparent transparent #ff3860 #ff3860 !important; +} + +.button.is-danger.is-outlined.is-loading:hover::after, .button.is-danger.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-outlined.is-loading:focus::after, .button.is-danger.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-danger.is-outlined[disabled], +fieldset[disabled] .button.is-danger.is-outlined { + background-color: transparent; + border-color: #ff3860; + box-shadow: none; + color: #ff3860; +} + +.button.is-danger.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-danger.is-inverted.is-outlined:hover, .button.is-danger.is-inverted.is-outlined.is-hovered, .button.is-danger.is-inverted.is-outlined:focus, .button.is-danger.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #ff3860; +} + +.button.is-danger.is-inverted.is-outlined.is-loading:hover::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-inverted.is-outlined.is-loading:focus::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #ff3860 #ff3860 !important; +} + +.button.is-danger.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-danger.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-small { + border-radius: 2px; + font-size: 0.75rem; +} + +.button.is-normal { + font-size: 1rem; +} + +.button.is-medium { + font-size: 1.25rem; +} + +.button.is-large { + font-size: 1.5rem; +} + +.button[disabled], +fieldset[disabled] .button { + background-color: white; + border-color: #dbdbdb; + box-shadow: none; + opacity: 0.5; +} + +.button.is-fullwidth { + display: flex; + width: 100%; +} + +.button.is-loading { + color: transparent !important; + pointer-events: none; +} + +.button.is-loading::after { + position: absolute; + left: calc(50% - (1em / 2)); + top: calc(50% - (1em / 2)); + position: absolute !important; +} + +.button.is-static { + background-color: whitesmoke; + border-color: #dbdbdb; + color: #7a7a7a; + box-shadow: none; + pointer-events: none; +} + +.button.is-rounded { + border-radius: 290486px; + padding-left: 1em; + padding-right: 1em; +} + +.buttons { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.buttons .button { + margin-bottom: 0.5rem; +} + +.buttons .button:not(:last-child):not(.is-fullwidth) { + margin-right: 0.5rem; +} + +.buttons:last-child { + margin-bottom: -0.5rem; +} + +.buttons:not(:last-child) { + margin-bottom: 1rem; +} + +.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large) { + border-radius: 2px; + font-size: 0.75rem; +} + +.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large) { + font-size: 1.25rem; +} + +.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium) { + font-size: 1.5rem; +} + +.buttons.has-addons .button:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.buttons.has-addons .button:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + margin-right: -1px; +} + +.buttons.has-addons .button:last-child { + margin-right: 0; +} + +.buttons.has-addons .button:hover, .buttons.has-addons .button.is-hovered { + z-index: 2; +} + +.buttons.has-addons .button:focus, .buttons.has-addons .button.is-focused, .buttons.has-addons .button:active, .buttons.has-addons .button.is-active, .buttons.has-addons .button.is-selected { + z-index: 3; +} + +.buttons.has-addons .button:focus:hover, .buttons.has-addons .button.is-focused:hover, .buttons.has-addons .button:active:hover, .buttons.has-addons .button.is-active:hover, .buttons.has-addons .button.is-selected:hover { + z-index: 4; +} + +.buttons.has-addons .button.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.buttons.is-centered { + justify-content: center; +} + +.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth) { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.buttons.is-right { + justify-content: flex-end; +} + +.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth) { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.container { + flex-grow: 1; + margin: 0 auto; + position: relative; + width: auto; +} + +@media screen and (min-width: 1024px) { + .container { + max-width: 960px; + } + .container.is-fluid { + margin-left: 32px; + margin-right: 32px; + max-width: none; + } +} + +@media screen and (max-width: 1215px) { + .container.is-widescreen { + max-width: 1152px; + } +} + +@media screen and (max-width: 1407px) { + .container.is-fullhd { + max-width: 1344px; + } +} + +@media screen and (min-width: 1216px) { + .container { + max-width: 1152px; + } +} + +@media screen and (min-width: 1408px) { + .container { + max-width: 1344px; + } +} + +.content li + li { + margin-top: 0.25em; +} + +.content p:not(:last-child), +.content dl:not(:last-child), +.content ol:not(:last-child), +.content ul:not(:last-child), +.content blockquote:not(:last-child), +.content pre:not(:last-child), +.content table:not(:last-child) { + margin-bottom: 1em; +} + +.content h1, +.content h2, +.content h3, +.content h4, +.content h5, +.content h6 { + color: #363636; + font-weight: 600; + line-height: 1.125; +} + +.content h1 { + font-size: 2em; + margin-bottom: 0.5em; +} + +.content h1:not(:first-child) { + margin-top: 1em; +} + +.content h2 { + font-size: 1.75em; + margin-bottom: 0.5714em; +} + +.content h2:not(:first-child) { + margin-top: 1.1428em; +} + +.content h3 { + font-size: 1.5em; + margin-bottom: 0.6666em; +} + +.content h3:not(:first-child) { + margin-top: 1.3333em; +} + +.content h4 { + font-size: 1.25em; + margin-bottom: 0.8em; +} + +.content h5 { + font-size: 1.125em; + margin-bottom: 0.8888em; +} + +.content h6 { + font-size: 1em; + margin-bottom: 1em; +} + +.content blockquote { + background-color: whitesmoke; + border-left: 5px solid #dbdbdb; + padding: 1.25em 1.5em; +} + +.content ol { + list-style-position: outside; + margin-left: 2em; + margin-top: 1em; +} + +.content ol:not([type]) { + list-style-type: decimal; +} + +.content ol:not([type]).is-lower-alpha { + list-style-type: lower-alpha; +} + +.content ol:not([type]).is-lower-roman { + list-style-type: lower-roman; +} + +.content ol:not([type]).is-upper-alpha { + list-style-type: upper-alpha; +} + +.content ol:not([type]).is-upper-roman { + list-style-type: upper-roman; +} + +.content ul { + list-style: disc outside; + margin-left: 2em; + margin-top: 1em; +} + +.content ul ul { + list-style-type: circle; + margin-top: 0.5em; +} + +.content ul ul ul { + list-style-type: square; +} + +.content dd { + margin-left: 2em; +} + +.content figure { + margin-left: 2em; + margin-right: 2em; + text-align: center; +} + +.content figure:not(:first-child) { + margin-top: 2em; +} + +.content figure:not(:last-child) { + margin-bottom: 2em; +} + +.content figure img { + display: inline-block; +} + +.content figure figcaption { + font-style: italic; +} + +.content pre { + -webkit-overflow-scrolling: touch; + overflow-x: auto; + padding: 1.25em 1.5em; + white-space: pre; + word-wrap: normal; +} + +.content sup, +.content sub { + font-size: 75%; +} + +.content table { + width: 100%; +} + +.content table td, +.content table th { + border: 1px solid #dbdbdb; + border-width: 0 0 1px; + padding: 0.5em 0.75em; + vertical-align: top; +} + +.content table th { + color: #363636; +} + +.content table th:not([align]) { + text-align: left; +} + +.content table thead td, +.content table thead th { + border-width: 0 0 2px; + color: #363636; +} + +.content table tfoot td, +.content table tfoot th { + border-width: 2px 0 0; + color: #363636; +} + +.content table tbody tr:last-child td, +.content table tbody tr:last-child th { + border-bottom-width: 0; +} + +.content .tabs li + li { + margin-top: 0; +} + +.content.is-small { + font-size: 0.75rem; +} + +.content.is-medium { + font-size: 1.25rem; +} + +.content.is-large { + font-size: 1.5rem; +} + +.icon { + align-items: center; + display: inline-flex; + justify-content: center; + height: 1.5rem; + width: 1.5rem; +} + +.icon.is-small { + height: 1rem; + width: 1rem; +} + +.icon.is-medium { + height: 2rem; + width: 2rem; +} + +.icon.is-large { + height: 3rem; + width: 3rem; +} + +.image { + display: block; + position: relative; +} + +.image img { + display: block; + height: auto; + width: 100%; +} + +.image img.is-rounded { + border-radius: 290486px; +} + +.image.is-square img, +.image.is-square .has-ratio, .image.is-1by1 img, +.image.is-1by1 .has-ratio, .image.is-5by4 img, +.image.is-5by4 .has-ratio, .image.is-4by3 img, +.image.is-4by3 .has-ratio, .image.is-3by2 img, +.image.is-3by2 .has-ratio, .image.is-5by3 img, +.image.is-5by3 .has-ratio, .image.is-16by9 img, +.image.is-16by9 .has-ratio, .image.is-2by1 img, +.image.is-2by1 .has-ratio, .image.is-3by1 img, +.image.is-3by1 .has-ratio, .image.is-4by5 img, +.image.is-4by5 .has-ratio, .image.is-3by4 img, +.image.is-3by4 .has-ratio, .image.is-2by3 img, +.image.is-2by3 .has-ratio, .image.is-3by5 img, +.image.is-3by5 .has-ratio, .image.is-9by16 img, +.image.is-9by16 .has-ratio, .image.is-1by2 img, +.image.is-1by2 .has-ratio, .image.is-1by3 img, +.image.is-1by3 .has-ratio { + height: 100%; + width: 100%; +} + +.image.is-square, .image.is-1by1 { + padding-top: 100%; +} + +.image.is-5by4 { + padding-top: 80%; +} + +.image.is-4by3 { + padding-top: 75%; +} + +.image.is-3by2 { + padding-top: 66.6666%; +} + +.image.is-5by3 { + padding-top: 60%; +} + +.image.is-16by9 { + padding-top: 56.25%; +} + +.image.is-2by1 { + padding-top: 50%; +} + +.image.is-3by1 { + padding-top: 33.3333%; +} + +.image.is-4by5 { + padding-top: 125%; +} + +.image.is-3by4 { + padding-top: 133.3333%; +} + +.image.is-2by3 { + padding-top: 150%; +} + +.image.is-3by5 { + padding-top: 166.6666%; +} + +.image.is-9by16 { + padding-top: 177.7777%; +} + +.image.is-1by2 { + padding-top: 200%; +} + +.image.is-1by3 { + padding-top: 300%; +} + +.image.is-16x16 { + height: 16px; + width: 16px; +} + +.image.is-24x24 { + height: 24px; + width: 24px; +} + +.image.is-32x32 { + height: 32px; + width: 32px; +} + +.image.is-48x48 { + height: 48px; + width: 48px; +} + +.image.is-64x64 { + height: 64px; + width: 64px; +} + +.image.is-96x96 { + height: 96px; + width: 96px; +} + +.image.is-128x128 { + height: 128px; + width: 128px; +} + +.notification { + background-color: whitesmoke; + border-radius: 4px; + padding: 1.25rem 2.5rem 1.25rem 1.5rem; + position: relative; +} + +.notification a:not(.button):not(.dropdown-item) { + color: currentColor; + text-decoration: underline; +} + +.notification strong { + color: currentColor; +} + +.notification code, +.notification pre { + background: white; +} + +.notification pre code { + background: transparent; +} + +.notification > .delete { + position: absolute; + right: 0.5rem; + top: 0.5rem; +} + +.notification .title, +.notification .subtitle, +.notification .content { + color: currentColor; +} + +.notification.is-white { + background-color: white; + color: #0a0a0a; +} + +.notification.is-black { + background-color: #0a0a0a; + color: white; +} + +.notification.is-light { + background-color: whitesmoke; + color: #363636; +} + +.notification.is-dark { + background-color: #363636; + color: whitesmoke; +} + +.notification.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.notification.is-link { + background-color: #3273dc; + color: #fff; +} + +.notification.is-info { + background-color: #209cee; + color: #fff; +} + +.notification.is-success { + background-color: #23d160; + color: #fff; +} + +.notification.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.notification.is-danger { + background-color: #ff3860; + color: #fff; +} + +.progress { + -moz-appearance: none; + -webkit-appearance: none; + border: none; + border-radius: 290486px; + display: block; + height: 1rem; + overflow: hidden; + padding: 0; + width: 100%; +} + +.progress::-webkit-progress-bar { + background-color: #dbdbdb; +} + +.progress::-webkit-progress-value { + background-color: #4a4a4a; +} + +.progress::-moz-progress-bar { + background-color: #4a4a4a; +} + +.progress::-ms-fill { + background-color: #4a4a4a; + border: none; +} + +.progress.is-white::-webkit-progress-value { + background-color: white; +} + +.progress.is-white::-moz-progress-bar { + background-color: white; +} + +.progress.is-white::-ms-fill { + background-color: white; +} + +.progress.is-white:indeterminate { + background-image: linear-gradient(to right, white 30%, #dbdbdb 30%); +} + +.progress.is-black::-webkit-progress-value { + background-color: #0a0a0a; +} + +.progress.is-black::-moz-progress-bar { + background-color: #0a0a0a; +} + +.progress.is-black::-ms-fill { + background-color: #0a0a0a; +} + +.progress.is-black:indeterminate { + background-image: linear-gradient(to right, #0a0a0a 30%, #dbdbdb 30%); +} + +.progress.is-light::-webkit-progress-value { + background-color: whitesmoke; +} + +.progress.is-light::-moz-progress-bar { + background-color: whitesmoke; +} + +.progress.is-light::-ms-fill { + background-color: whitesmoke; +} + +.progress.is-light:indeterminate { + background-image: linear-gradient(to right, whitesmoke 30%, #dbdbdb 30%); +} + +.progress.is-dark::-webkit-progress-value { + background-color: #363636; +} + +.progress.is-dark::-moz-progress-bar { + background-color: #363636; +} + +.progress.is-dark::-ms-fill { + background-color: #363636; +} + +.progress.is-dark:indeterminate { + background-image: linear-gradient(to right, #363636 30%, #dbdbdb 30%); +} + +.progress.is-primary::-webkit-progress-value { + background-color: #00d1b2; +} + +.progress.is-primary::-moz-progress-bar { + background-color: #00d1b2; +} + +.progress.is-primary::-ms-fill { + background-color: #00d1b2; +} + +.progress.is-primary:indeterminate { + background-image: linear-gradient(to right, #00d1b2 30%, #dbdbdb 30%); +} + +.progress.is-link::-webkit-progress-value { + background-color: #3273dc; +} + +.progress.is-link::-moz-progress-bar { + background-color: #3273dc; +} + +.progress.is-link::-ms-fill { + background-color: #3273dc; +} + +.progress.is-link:indeterminate { + background-image: linear-gradient(to right, #3273dc 30%, #dbdbdb 30%); +} + +.progress.is-info::-webkit-progress-value { + background-color: #209cee; +} + +.progress.is-info::-moz-progress-bar { + background-color: #209cee; +} + +.progress.is-info::-ms-fill { + background-color: #209cee; +} + +.progress.is-info:indeterminate { + background-image: linear-gradient(to right, #209cee 30%, #dbdbdb 30%); +} + +.progress.is-success::-webkit-progress-value { + background-color: #23d160; +} + +.progress.is-success::-moz-progress-bar { + background-color: #23d160; +} + +.progress.is-success::-ms-fill { + background-color: #23d160; +} + +.progress.is-success:indeterminate { + background-image: linear-gradient(to right, #23d160 30%, #dbdbdb 30%); +} + +.progress.is-warning::-webkit-progress-value { + background-color: #ffdd57; +} + +.progress.is-warning::-moz-progress-bar { + background-color: #ffdd57; +} + +.progress.is-warning::-ms-fill { + background-color: #ffdd57; +} + +.progress.is-warning:indeterminate { + background-image: linear-gradient(to right, #ffdd57 30%, #dbdbdb 30%); +} + +.progress.is-danger::-webkit-progress-value { + background-color: #ff3860; +} + +.progress.is-danger::-moz-progress-bar { + background-color: #ff3860; +} + +.progress.is-danger::-ms-fill { + background-color: #ff3860; +} + +.progress.is-danger:indeterminate { + background-image: linear-gradient(to right, #ff3860 30%, #dbdbdb 30%); +} + +.progress:indeterminate { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-name: moveIndeterminate; + animation-name: moveIndeterminate; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; + background-color: #dbdbdb; + background-image: linear-gradient(to right, #4a4a4a 30%, #dbdbdb 30%); + background-position: top left; + background-repeat: no-repeat; + background-size: 150% 150%; +} + +.progress:indeterminate::-webkit-progress-bar { + background-color: transparent; +} + +.progress:indeterminate::-moz-progress-bar { + background-color: transparent; +} + +.progress.is-small { + height: 0.75rem; +} + +.progress.is-medium { + height: 1.25rem; +} + +.progress.is-large { + height: 1.5rem; +} + +@-webkit-keyframes moveIndeterminate { + from { + background-position: 200% 0; + } + to { + background-position: -200% 0; + } +} + +@keyframes moveIndeterminate { + from { + background-position: 200% 0; + } + to { + background-position: -200% 0; + } +} + +.table { + background-color: white; + color: #363636; +} + +.table td, +.table th { + border: 1px solid #dbdbdb; + border-width: 0 0 1px; + padding: 0.5em 0.75em; + vertical-align: top; +} + +.table td.is-white, +.table th.is-white { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.table td.is-black, +.table th.is-black { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.table td.is-light, +.table th.is-light { + background-color: whitesmoke; + border-color: whitesmoke; + color: #363636; +} + +.table td.is-dark, +.table th.is-dark { + background-color: #363636; + border-color: #363636; + color: whitesmoke; +} + +.table td.is-primary, +.table th.is-primary { + background-color: #00d1b2; + border-color: #00d1b2; + color: #fff; +} + +.table td.is-link, +.table th.is-link { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.table td.is-info, +.table th.is-info { + background-color: #209cee; + border-color: #209cee; + color: #fff; +} + +.table td.is-success, +.table th.is-success { + background-color: #23d160; + border-color: #23d160; + color: #fff; +} + +.table td.is-warning, +.table th.is-warning { + background-color: #ffdd57; + border-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.table td.is-danger, +.table th.is-danger { + background-color: #ff3860; + border-color: #ff3860; + color: #fff; +} + +.table td.is-narrow, +.table th.is-narrow { + white-space: nowrap; + width: 1%; +} + +.table td.is-selected, +.table th.is-selected { + background-color: #00d1b2; + color: #fff; +} + +.table td.is-selected a, +.table td.is-selected strong, +.table th.is-selected a, +.table th.is-selected strong { + color: currentColor; +} + +.table th { + color: #363636; +} + +.table th:not([align]) { + text-align: left; +} + +.table tr.is-selected { + background-color: #00d1b2; + color: #fff; +} + +.table tr.is-selected a, +.table tr.is-selected strong { + color: currentColor; +} + +.table tr.is-selected td, +.table tr.is-selected th { + border-color: #fff; + color: currentColor; +} + +.table thead { + background-color: transparent; +} + +.table thead td, +.table thead th { + border-width: 0 0 2px; + color: #363636; +} + +.table tfoot { + background-color: transparent; +} + +.table tfoot td, +.table tfoot th { + border-width: 2px 0 0; + color: #363636; +} + +.table tbody { + background-color: transparent; +} + +.table tbody tr:last-child td, +.table tbody tr:last-child th { + border-bottom-width: 0; +} + +.table.is-bordered td, +.table.is-bordered th { + border-width: 1px; +} + +.table.is-bordered tr:last-child td, +.table.is-bordered tr:last-child th { + border-bottom-width: 1px; +} + +.table.is-fullwidth { + width: 100%; +} + +.table.is-hoverable tbody tr:not(.is-selected):hover { + background-color: #fafafa; +} + +.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover { + background-color: #fafafa; +} + +.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even) { + background-color: whitesmoke; +} + +.table.is-narrow td, +.table.is-narrow th { + padding: 0.25em 0.5em; +} + +.table.is-striped tbody tr:not(.is-selected):nth-child(even) { + background-color: #fafafa; +} + +.table-container { + -webkit-overflow-scrolling: touch; + overflow: auto; + overflow-y: hidden; + max-width: 100%; +} + +.tags { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.tags .tag { + margin-bottom: 0.5rem; +} + +.tags .tag:not(:last-child) { + margin-right: 0.5rem; +} + +.tags:last-child { + margin-bottom: -0.5rem; +} + +.tags:not(:last-child) { + margin-bottom: 1rem; +} + +.tags.are-medium .tag:not(.is-normal):not(.is-large) { + font-size: 1rem; +} + +.tags.are-large .tag:not(.is-normal):not(.is-medium) { + font-size: 1.25rem; +} + +.tags.is-centered { + justify-content: center; +} + +.tags.is-centered .tag { + margin-right: 0.25rem; + margin-left: 0.25rem; +} + +.tags.is-right { + justify-content: flex-end; +} + +.tags.is-right .tag:not(:first-child) { + margin-left: 0.5rem; +} + +.tags.is-right .tag:not(:last-child) { + margin-right: 0; +} + +.tags.has-addons .tag { + margin-right: 0; +} + +.tags.has-addons .tag:not(:first-child) { + margin-left: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.tags.has-addons .tag:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.tag:not(body) { + align-items: center; + background-color: whitesmoke; + border-radius: 4px; + color: #4a4a4a; + display: inline-flex; + font-size: 0.75rem; + height: 2em; + justify-content: center; + line-height: 1.5; + padding-left: 0.75em; + padding-right: 0.75em; + white-space: nowrap; +} + +.tag:not(body) .delete { + margin-left: 0.25rem; + margin-right: -0.375rem; +} + +.tag:not(body).is-white { + background-color: white; + color: #0a0a0a; +} + +.tag:not(body).is-black { + background-color: #0a0a0a; + color: white; +} + +.tag:not(body).is-light { + background-color: whitesmoke; + color: #363636; +} + +.tag:not(body).is-dark { + background-color: #363636; + color: whitesmoke; +} + +.tag:not(body).is-primary { + background-color: #00d1b2; + color: #fff; +} + +.tag:not(body).is-link { + background-color: #3273dc; + color: #fff; +} + +.tag:not(body).is-info { + background-color: #209cee; + color: #fff; +} + +.tag:not(body).is-success { + background-color: #23d160; + color: #fff; +} + +.tag:not(body).is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.tag:not(body).is-danger { + background-color: #ff3860; + color: #fff; +} + +.tag:not(body).is-normal { + font-size: 0.75rem; +} + +.tag:not(body).is-medium { + font-size: 1rem; +} + +.tag:not(body).is-large { + font-size: 1.25rem; +} + +.tag:not(body) .icon:first-child:not(:last-child) { + margin-left: -0.375em; + margin-right: 0.1875em; +} + +.tag:not(body) .icon:last-child:not(:first-child) { + margin-left: 0.1875em; + margin-right: -0.375em; +} + +.tag:not(body) .icon:first-child:last-child { + margin-left: -0.375em; + margin-right: -0.375em; +} + +.tag:not(body).is-delete { + margin-left: 1px; + padding: 0; + position: relative; + width: 2em; +} + +.tag:not(body).is-delete::before, .tag:not(body).is-delete::after { + background-color: currentColor; + content: ""; + display: block; + left: 50%; + position: absolute; + top: 50%; + -webkit-transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform: translateX(-50%) translateY(-50%) rotate(45deg); + -webkit-transform-origin: center center; + transform-origin: center center; +} + +.tag:not(body).is-delete::before { + height: 1px; + width: 50%; +} + +.tag:not(body).is-delete::after { + height: 50%; + width: 1px; +} + +.tag:not(body).is-delete:hover, .tag:not(body).is-delete:focus { + background-color: #e8e8e8; +} + +.tag:not(body).is-delete:active { + background-color: #dbdbdb; +} + +.tag:not(body).is-rounded { + border-radius: 290486px; +} + +a.tag:hover { + text-decoration: underline; +} + +.title, +.subtitle { + word-break: break-word; +} + +.title em, +.title span, +.subtitle em, +.subtitle span { + font-weight: inherit; +} + +.title sub, +.subtitle sub { + font-size: 0.75em; +} + +.title sup, +.subtitle sup { + font-size: 0.75em; +} + +.title .tag, +.subtitle .tag { + vertical-align: middle; +} + +.title { + color: #363636; + font-size: 2rem; + font-weight: 600; + line-height: 1.125; +} + +.title strong { + color: inherit; + font-weight: inherit; +} + +.title + .highlight { + margin-top: -0.75rem; +} + +.title:not(.is-spaced) + .subtitle { + margin-top: -1.25rem; +} + +.title.is-1 { + font-size: 3rem; +} + +.title.is-2 { + font-size: 2.5rem; +} + +.title.is-3 { + font-size: 2rem; +} + +.title.is-4 { + font-size: 1.5rem; +} + +.title.is-5 { + font-size: 1.25rem; +} + +.title.is-6 { + font-size: 1rem; +} + +.title.is-7 { + font-size: 0.75rem; +} + +.subtitle { + color: #4a4a4a; + font-size: 1.25rem; + font-weight: 400; + line-height: 1.25; +} + +.subtitle strong { + color: #363636; + font-weight: 600; +} + +.subtitle:not(.is-spaced) + .title { + margin-top: -1.25rem; +} + +.subtitle.is-1 { + font-size: 3rem; +} + +.subtitle.is-2 { + font-size: 2.5rem; +} + +.subtitle.is-3 { + font-size: 2rem; +} + +.subtitle.is-4 { + font-size: 1.5rem; +} + +.subtitle.is-5 { + font-size: 1.25rem; +} + +.subtitle.is-6 { + font-size: 1rem; +} + +.subtitle.is-7 { + font-size: 0.75rem; +} + +.heading { + display: block; + font-size: 11px; + letter-spacing: 1px; + margin-bottom: 5px; + text-transform: uppercase; +} + +.highlight { + font-weight: 400; + max-width: 100%; + overflow: hidden; + padding: 0; +} + +.highlight pre { + overflow: auto; + max-width: 100%; +} + +.number { + align-items: center; + background-color: whitesmoke; + border-radius: 290486px; + display: inline-flex; + font-size: 1.25rem; + height: 2em; + justify-content: center; + margin-right: 1.5rem; + min-width: 2.5em; + padding: 0.25rem 0.5rem; + text-align: center; + vertical-align: top; +} + +.input, .textarea, .select select { + background-color: white; + border-color: #dbdbdb; + border-radius: 4px; + color: #363636; +} + +.input::-moz-placeholder, .textarea::-moz-placeholder, .select select::-moz-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input::-webkit-input-placeholder, .textarea::-webkit-input-placeholder, .select select::-webkit-input-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:-moz-placeholder, .textarea:-moz-placeholder, .select select:-moz-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:-ms-input-placeholder, .textarea:-ms-input-placeholder, .select select:-ms-input-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:hover, .textarea:hover, .select select:hover, .is-hovered.input, .is-hovered.textarea, .select select.is-hovered { + border-color: #b5b5b5; +} + +.input:focus, .textarea:focus, .select select:focus, .is-focused.input, .is-focused.textarea, .select select.is-focused, .input:active, .textarea:active, .select select:active, .is-active.input, .is-active.textarea, .select select.is-active { + border-color: #3273dc; + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.input[disabled], .textarea[disabled], .select select[disabled], +fieldset[disabled] .input, +fieldset[disabled] .textarea, +fieldset[disabled] .select select, +.select fieldset[disabled] select { + background-color: whitesmoke; + border-color: whitesmoke; + box-shadow: none; + color: #7a7a7a; +} + +.input[disabled]::-moz-placeholder, .textarea[disabled]::-moz-placeholder, .select select[disabled]::-moz-placeholder, +fieldset[disabled] .input::-moz-placeholder, +fieldset[disabled] .textarea::-moz-placeholder, +fieldset[disabled] .select select::-moz-placeholder, +.select fieldset[disabled] select::-moz-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]::-webkit-input-placeholder, .textarea[disabled]::-webkit-input-placeholder, .select select[disabled]::-webkit-input-placeholder, +fieldset[disabled] .input::-webkit-input-placeholder, +fieldset[disabled] .textarea::-webkit-input-placeholder, +fieldset[disabled] .select select::-webkit-input-placeholder, +.select fieldset[disabled] select::-webkit-input-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]:-moz-placeholder, .textarea[disabled]:-moz-placeholder, .select select[disabled]:-moz-placeholder, +fieldset[disabled] .input:-moz-placeholder, +fieldset[disabled] .textarea:-moz-placeholder, +fieldset[disabled] .select select:-moz-placeholder, +.select fieldset[disabled] select:-moz-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]:-ms-input-placeholder, .textarea[disabled]:-ms-input-placeholder, .select select[disabled]:-ms-input-placeholder, +fieldset[disabled] .input:-ms-input-placeholder, +fieldset[disabled] .textarea:-ms-input-placeholder, +fieldset[disabled] .select select:-ms-input-placeholder, +.select fieldset[disabled] select:-ms-input-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input, .textarea { + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1); + max-width: 100%; + width: 100%; +} + +.input[readonly], .textarea[readonly] { + box-shadow: none; +} + +.is-white.input, .is-white.textarea { + border-color: white; +} + +.is-white.input:focus, .is-white.textarea:focus, .is-white.is-focused.input, .is-white.is-focused.textarea, .is-white.input:active, .is-white.textarea:active, .is-white.is-active.input, .is-white.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.is-black.input, .is-black.textarea { + border-color: #0a0a0a; +} + +.is-black.input:focus, .is-black.textarea:focus, .is-black.is-focused.input, .is-black.is-focused.textarea, .is-black.input:active, .is-black.textarea:active, .is-black.is-active.input, .is-black.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.is-light.input, .is-light.textarea { + border-color: whitesmoke; +} + +.is-light.input:focus, .is-light.textarea:focus, .is-light.is-focused.input, .is-light.is-focused.textarea, .is-light.input:active, .is-light.textarea:active, .is-light.is-active.input, .is-light.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.is-dark.input, .is-dark.textarea { + border-color: #363636; +} + +.is-dark.input:focus, .is-dark.textarea:focus, .is-dark.is-focused.input, .is-dark.is-focused.textarea, .is-dark.input:active, .is-dark.textarea:active, .is-dark.is-active.input, .is-dark.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.is-primary.input, .is-primary.textarea { + border-color: #00d1b2; +} + +.is-primary.input:focus, .is-primary.textarea:focus, .is-primary.is-focused.input, .is-primary.is-focused.textarea, .is-primary.input:active, .is-primary.textarea:active, .is-primary.is-active.input, .is-primary.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.is-link.input, .is-link.textarea { + border-color: #3273dc; +} + +.is-link.input:focus, .is-link.textarea:focus, .is-link.is-focused.input, .is-link.is-focused.textarea, .is-link.input:active, .is-link.textarea:active, .is-link.is-active.input, .is-link.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.is-info.input, .is-info.textarea { + border-color: #209cee; +} + +.is-info.input:focus, .is-info.textarea:focus, .is-info.is-focused.input, .is-info.is-focused.textarea, .is-info.input:active, .is-info.textarea:active, .is-info.is-active.input, .is-info.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(32, 156, 238, 0.25); +} + +.is-success.input, .is-success.textarea { + border-color: #23d160; +} + +.is-success.input:focus, .is-success.textarea:focus, .is-success.is-focused.input, .is-success.is-focused.textarea, .is-success.input:active, .is-success.textarea:active, .is-success.is-active.input, .is-success.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(35, 209, 96, 0.25); +} + +.is-warning.input, .is-warning.textarea { + border-color: #ffdd57; +} + +.is-warning.input:focus, .is-warning.textarea:focus, .is-warning.is-focused.input, .is-warning.is-focused.textarea, .is-warning.input:active, .is-warning.textarea:active, .is-warning.is-active.input, .is-warning.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.is-danger.input, .is-danger.textarea { + border-color: #ff3860; +} + +.is-danger.input:focus, .is-danger.textarea:focus, .is-danger.is-focused.input, .is-danger.is-focused.textarea, .is-danger.input:active, .is-danger.textarea:active, .is-danger.is-active.input, .is-danger.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(255, 56, 96, 0.25); +} + +.is-small.input, .is-small.textarea { + border-radius: 2px; + font-size: 0.75rem; +} + +.is-medium.input, .is-medium.textarea { + font-size: 1.25rem; +} + +.is-large.input, .is-large.textarea { + font-size: 1.5rem; +} + +.is-fullwidth.input, .is-fullwidth.textarea { + display: block; + width: 100%; +} + +.is-inline.input, .is-inline.textarea { + display: inline; + width: auto; +} + +.input.is-rounded { + border-radius: 290486px; + padding-left: 1em; + padding-right: 1em; +} + +.input.is-static { + background-color: transparent; + border-color: transparent; + box-shadow: none; + padding-left: 0; + padding-right: 0; +} + +.textarea { + display: block; + max-width: 100%; + min-width: 100%; + padding: 0.625em; + resize: vertical; +} + +.textarea:not([rows]) { + max-height: 600px; + min-height: 120px; +} + +.textarea[rows] { + height: initial; +} + +.textarea.has-fixed-size { + resize: none; +} + +.checkbox, .radio { + cursor: pointer; + display: inline-block; + line-height: 1.25; + position: relative; +} + +.checkbox input, .radio input { + cursor: pointer; +} + +.checkbox:hover, .radio:hover { + color: #363636; +} + +.checkbox[disabled], .radio[disabled], +fieldset[disabled] .checkbox, +fieldset[disabled] .radio { + color: #7a7a7a; + cursor: not-allowed; +} + +.radio + .radio { + margin-left: 0.5em; +} + +.select { + display: inline-block; + max-width: 100%; + position: relative; + vertical-align: top; +} + +.select:not(.is-multiple) { + height: 2.25em; +} + +.select:not(.is-multiple):not(.is-loading)::after { + border-color: #3273dc; + right: 1.125em; + z-index: 4; +} + +.select.is-rounded select { + border-radius: 290486px; + padding-left: 1em; +} + +.select select { + cursor: pointer; + display: block; + font-size: 1em; + max-width: 100%; + outline: none; +} + +.select select::-ms-expand { + display: none; +} + +.select select[disabled]:hover, +fieldset[disabled] .select select:hover { + border-color: whitesmoke; +} + +.select select:not([multiple]) { + padding-right: 2.5em; +} + +.select select[multiple] { + height: auto; + padding: 0; +} + +.select select[multiple] option { + padding: 0.5em 1em; +} + +.select:not(.is-multiple):not(.is-loading):hover::after { + border-color: #363636; +} + +.select.is-white:not(:hover)::after { + border-color: white; +} + +.select.is-white select { + border-color: white; +} + +.select.is-white select:hover, .select.is-white select.is-hovered { + border-color: #f2f2f2; +} + +.select.is-white select:focus, .select.is-white select.is-focused, .select.is-white select:active, .select.is-white select.is-active { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.select.is-black:not(:hover)::after { + border-color: #0a0a0a; +} + +.select.is-black select { + border-color: #0a0a0a; +} + +.select.is-black select:hover, .select.is-black select.is-hovered { + border-color: black; +} + +.select.is-black select:focus, .select.is-black select.is-focused, .select.is-black select:active, .select.is-black select.is-active { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.select.is-light:not(:hover)::after { + border-color: whitesmoke; +} + +.select.is-light select { + border-color: whitesmoke; +} + +.select.is-light select:hover, .select.is-light select.is-hovered { + border-color: #e8e8e8; +} + +.select.is-light select:focus, .select.is-light select.is-focused, .select.is-light select:active, .select.is-light select.is-active { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.select.is-dark:not(:hover)::after { + border-color: #363636; +} + +.select.is-dark select { + border-color: #363636; +} + +.select.is-dark select:hover, .select.is-dark select.is-hovered { + border-color: #292929; +} + +.select.is-dark select:focus, .select.is-dark select.is-focused, .select.is-dark select:active, .select.is-dark select.is-active { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.select.is-primary:not(:hover)::after { + border-color: #00d1b2; +} + +.select.is-primary select { + border-color: #00d1b2; +} + +.select.is-primary select:hover, .select.is-primary select.is-hovered { + border-color: #00b89c; +} + +.select.is-primary select:focus, .select.is-primary select.is-focused, .select.is-primary select:active, .select.is-primary select.is-active { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.select.is-link:not(:hover)::after { + border-color: #3273dc; +} + +.select.is-link select { + border-color: #3273dc; +} + +.select.is-link select:hover, .select.is-link select.is-hovered { + border-color: #2366d1; +} + +.select.is-link select:focus, .select.is-link select.is-focused, .select.is-link select:active, .select.is-link select.is-active { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.select.is-info:not(:hover)::after { + border-color: #209cee; +} + +.select.is-info select { + border-color: #209cee; +} + +.select.is-info select:hover, .select.is-info select.is-hovered { + border-color: #118fe4; +} + +.select.is-info select:focus, .select.is-info select.is-focused, .select.is-info select:active, .select.is-info select.is-active { + box-shadow: 0 0 0 0.125em rgba(32, 156, 238, 0.25); +} + +.select.is-success:not(:hover)::after { + border-color: #23d160; +} + +.select.is-success select { + border-color: #23d160; +} + +.select.is-success select:hover, .select.is-success select.is-hovered { + border-color: #20bc56; +} + +.select.is-success select:focus, .select.is-success select.is-focused, .select.is-success select:active, .select.is-success select.is-active { + box-shadow: 0 0 0 0.125em rgba(35, 209, 96, 0.25); +} + +.select.is-warning:not(:hover)::after { + border-color: #ffdd57; +} + +.select.is-warning select { + border-color: #ffdd57; +} + +.select.is-warning select:hover, .select.is-warning select.is-hovered { + border-color: #ffd83d; +} + +.select.is-warning select:focus, .select.is-warning select.is-focused, .select.is-warning select:active, .select.is-warning select.is-active { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.select.is-danger:not(:hover)::after { + border-color: #ff3860; +} + +.select.is-danger select { + border-color: #ff3860; +} + +.select.is-danger select:hover, .select.is-danger select.is-hovered { + border-color: #ff1f4b; +} + +.select.is-danger select:focus, .select.is-danger select.is-focused, .select.is-danger select:active, .select.is-danger select.is-active { + box-shadow: 0 0 0 0.125em rgba(255, 56, 96, 0.25); +} + +.select.is-small { + border-radius: 2px; + font-size: 0.75rem; +} + +.select.is-medium { + font-size: 1.25rem; +} + +.select.is-large { + font-size: 1.5rem; +} + +.select.is-disabled::after { + border-color: #7a7a7a; +} + +.select.is-fullwidth { + width: 100%; +} + +.select.is-fullwidth select { + width: 100%; +} + +.select.is-loading::after { + margin-top: 0; + position: absolute; + right: 0.625em; + top: 0.625em; + -webkit-transform: none; + transform: none; +} + +.select.is-loading.is-small:after { + font-size: 0.75rem; +} + +.select.is-loading.is-medium:after { + font-size: 1.25rem; +} + +.select.is-loading.is-large:after { + font-size: 1.5rem; +} + +.file { + align-items: stretch; + display: flex; + justify-content: flex-start; + position: relative; +} + +.file.is-white .file-cta { + background-color: white; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-white:hover .file-cta, .file.is-white.is-hovered .file-cta { + background-color: #f9f9f9; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-white:focus .file-cta, .file.is-white.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(255, 255, 255, 0.25); + color: #0a0a0a; +} + +.file.is-white:active .file-cta, .file.is-white.is-active .file-cta { + background-color: #f2f2f2; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-black .file-cta { + background-color: #0a0a0a; + border-color: transparent; + color: white; +} + +.file.is-black:hover .file-cta, .file.is-black.is-hovered .file-cta { + background-color: #040404; + border-color: transparent; + color: white; +} + +.file.is-black:focus .file-cta, .file.is-black.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(10, 10, 10, 0.25); + color: white; +} + +.file.is-black:active .file-cta, .file.is-black.is-active .file-cta { + background-color: black; + border-color: transparent; + color: white; +} + +.file.is-light .file-cta { + background-color: whitesmoke; + border-color: transparent; + color: #363636; +} + +.file.is-light:hover .file-cta, .file.is-light.is-hovered .file-cta { + background-color: #eeeeee; + border-color: transparent; + color: #363636; +} + +.file.is-light:focus .file-cta, .file.is-light.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(245, 245, 245, 0.25); + color: #363636; +} + +.file.is-light:active .file-cta, .file.is-light.is-active .file-cta { + background-color: #e8e8e8; + border-color: transparent; + color: #363636; +} + +.file.is-dark .file-cta { + background-color: #363636; + border-color: transparent; + color: whitesmoke; +} + +.file.is-dark:hover .file-cta, .file.is-dark.is-hovered .file-cta { + background-color: #2f2f2f; + border-color: transparent; + color: whitesmoke; +} + +.file.is-dark:focus .file-cta, .file.is-dark.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(54, 54, 54, 0.25); + color: whitesmoke; +} + +.file.is-dark:active .file-cta, .file.is-dark.is-active .file-cta { + background-color: #292929; + border-color: transparent; + color: whitesmoke; +} + +.file.is-primary .file-cta { + background-color: #00d1b2; + border-color: transparent; + color: #fff; +} + +.file.is-primary:hover .file-cta, .file.is-primary.is-hovered .file-cta { + background-color: #00c4a7; + border-color: transparent; + color: #fff; +} + +.file.is-primary:focus .file-cta, .file.is-primary.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(0, 209, 178, 0.25); + color: #fff; +} + +.file.is-primary:active .file-cta, .file.is-primary.is-active .file-cta { + background-color: #00b89c; + border-color: transparent; + color: #fff; +} + +.file.is-link .file-cta { + background-color: #3273dc; + border-color: transparent; + color: #fff; +} + +.file.is-link:hover .file-cta, .file.is-link.is-hovered .file-cta { + background-color: #276cda; + border-color: transparent; + color: #fff; +} + +.file.is-link:focus .file-cta, .file.is-link.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(50, 115, 220, 0.25); + color: #fff; +} + +.file.is-link:active .file-cta, .file.is-link.is-active .file-cta { + background-color: #2366d1; + border-color: transparent; + color: #fff; +} + +.file.is-info .file-cta { + background-color: #209cee; + border-color: transparent; + color: #fff; +} + +.file.is-info:hover .file-cta, .file.is-info.is-hovered .file-cta { + background-color: #1496ed; + border-color: transparent; + color: #fff; +} + +.file.is-info:focus .file-cta, .file.is-info.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(32, 156, 238, 0.25); + color: #fff; +} + +.file.is-info:active .file-cta, .file.is-info.is-active .file-cta { + background-color: #118fe4; + border-color: transparent; + color: #fff; +} + +.file.is-success .file-cta { + background-color: #23d160; + border-color: transparent; + color: #fff; +} + +.file.is-success:hover .file-cta, .file.is-success.is-hovered .file-cta { + background-color: #22c65b; + border-color: transparent; + color: #fff; +} + +.file.is-success:focus .file-cta, .file.is-success.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(35, 209, 96, 0.25); + color: #fff; +} + +.file.is-success:active .file-cta, .file.is-success.is-active .file-cta { + background-color: #20bc56; + border-color: transparent; + color: #fff; +} + +.file.is-warning .file-cta { + background-color: #ffdd57; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:hover .file-cta, .file.is-warning.is-hovered .file-cta { + background-color: #ffdb4a; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:focus .file-cta, .file.is-warning.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(255, 221, 87, 0.25); + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:active .file-cta, .file.is-warning.is-active .file-cta { + background-color: #ffd83d; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-danger .file-cta { + background-color: #ff3860; + border-color: transparent; + color: #fff; +} + +.file.is-danger:hover .file-cta, .file.is-danger.is-hovered .file-cta { + background-color: #ff2b56; + border-color: transparent; + color: #fff; +} + +.file.is-danger:focus .file-cta, .file.is-danger.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(255, 56, 96, 0.25); + color: #fff; +} + +.file.is-danger:active .file-cta, .file.is-danger.is-active .file-cta { + background-color: #ff1f4b; + border-color: transparent; + color: #fff; +} + +.file.is-small { + font-size: 0.75rem; +} + +.file.is-medium { + font-size: 1.25rem; +} + +.file.is-medium .file-icon .fa { + font-size: 21px; +} + +.file.is-large { + font-size: 1.5rem; +} + +.file.is-large .file-icon .fa { + font-size: 28px; +} + +.file.has-name .file-cta { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.file.has-name .file-name { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.file.has-name.is-empty .file-cta { + border-radius: 4px; +} + +.file.has-name.is-empty .file-name { + display: none; +} + +.file.is-boxed .file-label { + flex-direction: column; +} + +.file.is-boxed .file-cta { + flex-direction: column; + height: auto; + padding: 1em 3em; +} + +.file.is-boxed .file-name { + border-width: 0 1px 1px; +} + +.file.is-boxed .file-icon { + height: 1.5em; + width: 1.5em; +} + +.file.is-boxed .file-icon .fa { + font-size: 21px; +} + +.file.is-boxed.is-small .file-icon .fa { + font-size: 14px; +} + +.file.is-boxed.is-medium .file-icon .fa { + font-size: 28px; +} + +.file.is-boxed.is-large .file-icon .fa { + font-size: 35px; +} + +.file.is-boxed.has-name .file-cta { + border-radius: 4px 4px 0 0; +} + +.file.is-boxed.has-name .file-name { + border-radius: 0 0 4px 4px; + border-width: 0 1px 1px; +} + +.file.is-centered { + justify-content: center; +} + +.file.is-fullwidth .file-label { + width: 100%; +} + +.file.is-fullwidth .file-name { + flex-grow: 1; + max-width: none; +} + +.file.is-right { + justify-content: flex-end; +} + +.file.is-right .file-cta { + border-radius: 0 4px 4px 0; +} + +.file.is-right .file-name { + border-radius: 4px 0 0 4px; + border-width: 1px 0 1px 1px; + order: -1; +} + +.file-label { + align-items: stretch; + display: flex; + cursor: pointer; + justify-content: flex-start; + overflow: hidden; + position: relative; +} + +.file-label:hover .file-cta { + background-color: #eeeeee; + color: #363636; +} + +.file-label:hover .file-name { + border-color: #d5d5d5; +} + +.file-label:active .file-cta { + background-color: #e8e8e8; + color: #363636; +} + +.file-label:active .file-name { + border-color: #cfcfcf; +} + +.file-input { + height: 100%; + left: 0; + opacity: 0; + outline: none; + position: absolute; + top: 0; + width: 100%; +} + +.file-cta, +.file-name { + border-color: #dbdbdb; + border-radius: 4px; + font-size: 1em; + padding-left: 1em; + padding-right: 1em; + white-space: nowrap; +} + +.file-cta { + background-color: whitesmoke; + color: #4a4a4a; +} + +.file-name { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px 1px 1px 0; + display: block; + max-width: 16em; + overflow: hidden; + text-align: left; + text-overflow: ellipsis; +} + +.file-icon { + align-items: center; + display: flex; + height: 1em; + justify-content: center; + margin-right: 0.5em; + width: 1em; +} + +.file-icon .fa { + font-size: 14px; +} + +.label { + color: #363636; + display: block; + font-size: 1rem; + font-weight: 700; +} + +.label:not(:last-child) { + margin-bottom: 0.5em; +} + +.label.is-small { + font-size: 0.75rem; +} + +.label.is-medium { + font-size: 1.25rem; +} + +.label.is-large { + font-size: 1.5rem; +} + +.help { + display: block; + font-size: 0.75rem; + margin-top: 0.25rem; +} + +.help.is-white { + color: white; +} + +.help.is-black { + color: #0a0a0a; +} + +.help.is-light { + color: whitesmoke; +} + +.help.is-dark { + color: #363636; +} + +.help.is-primary { + color: #00d1b2; +} + +.help.is-link { + color: #3273dc; +} + +.help.is-info { + color: #209cee; +} + +.help.is-success { + color: #23d160; +} + +.help.is-warning { + color: #ffdd57; +} + +.help.is-danger { + color: #ff3860; +} + +.field:not(:last-child) { + margin-bottom: 0.75rem; +} + +.field.has-addons { + display: flex; + justify-content: flex-start; +} + +.field.has-addons .control:not(:last-child) { + margin-right: -1px; +} + +.field.has-addons .control:not(:first-child):not(:last-child) .button, +.field.has-addons .control:not(:first-child):not(:last-child) .input, +.field.has-addons .control:not(:first-child):not(:last-child) .select select { + border-radius: 0; +} + +.field.has-addons .control:first-child:not(:only-child) .button, +.field.has-addons .control:first-child:not(:only-child) .input, +.field.has-addons .control:first-child:not(:only-child) .select select { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.field.has-addons .control:last-child:not(:only-child) .button, +.field.has-addons .control:last-child:not(:only-child) .input, +.field.has-addons .control:last-child:not(:only-child) .select select { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.field.has-addons .control .button:not([disabled]):hover, .field.has-addons .control .button:not([disabled]).is-hovered, +.field.has-addons .control .input:not([disabled]):hover, +.field.has-addons .control .input:not([disabled]).is-hovered, +.field.has-addons .control .select select:not([disabled]):hover, +.field.has-addons .control .select select:not([disabled]).is-hovered { + z-index: 2; +} + +.field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active, +.field.has-addons .control .input:not([disabled]):focus, +.field.has-addons .control .input:not([disabled]).is-focused, +.field.has-addons .control .input:not([disabled]):active, +.field.has-addons .control .input:not([disabled]).is-active, +.field.has-addons .control .select select:not([disabled]):focus, +.field.has-addons .control .select select:not([disabled]).is-focused, +.field.has-addons .control .select select:not([disabled]):active, +.field.has-addons .control .select select:not([disabled]).is-active { + z-index: 3; +} + +.field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active:hover, +.field.has-addons .control .input:not([disabled]):focus:hover, +.field.has-addons .control .input:not([disabled]).is-focused:hover, +.field.has-addons .control .input:not([disabled]):active:hover, +.field.has-addons .control .input:not([disabled]).is-active:hover, +.field.has-addons .control .select select:not([disabled]):focus:hover, +.field.has-addons .control .select select:not([disabled]).is-focused:hover, +.field.has-addons .control .select select:not([disabled]):active:hover, +.field.has-addons .control .select select:not([disabled]).is-active:hover { + z-index: 4; +} + +.field.has-addons .control.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.field.has-addons.has-addons-centered { + justify-content: center; +} + +.field.has-addons.has-addons-right { + justify-content: flex-end; +} + +.field.has-addons.has-addons-fullwidth .control { + flex-grow: 1; + flex-shrink: 0; +} + +.field.is-grouped { + display: flex; + justify-content: flex-start; +} + +.field.is-grouped > .control { + flex-shrink: 0; +} + +.field.is-grouped > .control:not(:last-child) { + margin-bottom: 0; + margin-right: 0.75rem; +} + +.field.is-grouped > .control.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.field.is-grouped.is-grouped-centered { + justify-content: center; +} + +.field.is-grouped.is-grouped-right { + justify-content: flex-end; +} + +.field.is-grouped.is-grouped-multiline { + flex-wrap: wrap; +} + +.field.is-grouped.is-grouped-multiline > .control:last-child, .field.is-grouped.is-grouped-multiline > .control:not(:last-child) { + margin-bottom: 0.75rem; +} + +.field.is-grouped.is-grouped-multiline:last-child { + margin-bottom: -0.75rem; +} + +.field.is-grouped.is-grouped-multiline:not(:last-child) { + margin-bottom: 0; +} + +@media screen and (min-width: 769px), print { + .field.is-horizontal { + display: flex; + } +} + +.field-label .label { + font-size: inherit; +} + +@media screen and (max-width: 768px) { + .field-label { + margin-bottom: 0.5rem; + } +} + +@media screen and (min-width: 769px), print { + .field-label { + flex-basis: 0; + flex-grow: 1; + flex-shrink: 0; + margin-right: 1.5rem; + text-align: right; + } + .field-label.is-small { + font-size: 0.75rem; + padding-top: 0.375em; + } + .field-label.is-normal { + padding-top: 0.375em; + } + .field-label.is-medium { + font-size: 1.25rem; + padding-top: 0.375em; + } + .field-label.is-large { + font-size: 1.5rem; + padding-top: 0.375em; + } +} + +.field-body .field .field { + margin-bottom: 0; +} + +@media screen and (min-width: 769px), print { + .field-body { + display: flex; + flex-basis: 0; + flex-grow: 5; + flex-shrink: 1; + } + .field-body .field { + margin-bottom: 0; + } + .field-body > .field { + flex-shrink: 1; + } + .field-body > .field:not(.is-narrow) { + flex-grow: 1; + } + .field-body > .field:not(:last-child) { + margin-right: 0.75rem; + } +} + +.control { + box-sizing: border-box; + clear: both; + font-size: 1rem; + position: relative; + text-align: left; +} + +.control.has-icons-left .input:focus ~ .icon, +.control.has-icons-left .select:focus ~ .icon, .control.has-icons-right .input:focus ~ .icon, +.control.has-icons-right .select:focus ~ .icon { + color: #7a7a7a; +} + +.control.has-icons-left .input.is-small ~ .icon, +.control.has-icons-left .select.is-small ~ .icon, .control.has-icons-right .input.is-small ~ .icon, +.control.has-icons-right .select.is-small ~ .icon { + font-size: 0.75rem; +} + +.control.has-icons-left .input.is-medium ~ .icon, +.control.has-icons-left .select.is-medium ~ .icon, .control.has-icons-right .input.is-medium ~ .icon, +.control.has-icons-right .select.is-medium ~ .icon { + font-size: 1.25rem; +} + +.control.has-icons-left .input.is-large ~ .icon, +.control.has-icons-left .select.is-large ~ .icon, .control.has-icons-right .input.is-large ~ .icon, +.control.has-icons-right .select.is-large ~ .icon { + font-size: 1.5rem; +} + +.control.has-icons-left .icon, .control.has-icons-right .icon { + color: #dbdbdb; + height: 2.25em; + pointer-events: none; + position: absolute; + top: 0; + width: 2.25em; + z-index: 4; +} + +.control.has-icons-left .input, +.control.has-icons-left .select select { + padding-left: 2.25em; +} + +.control.has-icons-left .icon.is-left { + left: 0; +} + +.control.has-icons-right .input, +.control.has-icons-right .select select { + padding-right: 2.25em; +} + +.control.has-icons-right .icon.is-right { + right: 0; +} + +.control.is-loading::after { + position: absolute !important; + right: 0.625em; + top: 0.625em; + z-index: 4; +} + +.control.is-loading.is-small:after { + font-size: 0.75rem; +} + +.control.is-loading.is-medium:after { + font-size: 1.25rem; +} + +.control.is-loading.is-large:after { + font-size: 1.5rem; +} + +.breadcrumb { + font-size: 1rem; + white-space: nowrap; +} + +.breadcrumb a { + align-items: center; + color: #3273dc; + display: flex; + justify-content: center; + padding: 0 0.75em; +} + +.breadcrumb a:hover { + color: #363636; +} + +.breadcrumb li { + align-items: center; + display: flex; +} + +.breadcrumb li:first-child a { + padding-left: 0; +} + +.breadcrumb li.is-active a { + color: #363636; + cursor: default; + pointer-events: none; +} + +.breadcrumb li + li::before { + color: #b5b5b5; + content: "\0002f"; +} + +.breadcrumb ul, +.breadcrumb ol { + align-items: flex-start; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.breadcrumb .icon:first-child { + margin-right: 0.5em; +} + +.breadcrumb .icon:last-child { + margin-left: 0.5em; +} + +.breadcrumb.is-centered ol, +.breadcrumb.is-centered ul { + justify-content: center; +} + +.breadcrumb.is-right ol, +.breadcrumb.is-right ul { + justify-content: flex-end; +} + +.breadcrumb.is-small { + font-size: 0.75rem; +} + +.breadcrumb.is-medium { + font-size: 1.25rem; +} + +.breadcrumb.is-large { + font-size: 1.5rem; +} + +.breadcrumb.has-arrow-separator li + li::before { + content: "\02192"; +} + +.breadcrumb.has-bullet-separator li + li::before { + content: "\02022"; +} + +.breadcrumb.has-dot-separator li + li::before { + content: "\000b7"; +} + +.breadcrumb.has-succeeds-separator li + li::before { + content: "\0227B"; +} + +.card { + background-color: white; + box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); + color: #4a4a4a; + max-width: 100%; + position: relative; +} + +.card-header { + background-color: transparent; + align-items: stretch; + box-shadow: 0 1px 2px rgba(10, 10, 10, 0.1); + display: flex; +} + +.card-header-title { + align-items: center; + color: #363636; + display: flex; + flex-grow: 1; + font-weight: 700; + padding: 0.75rem; +} + +.card-header-title.is-centered { + justify-content: center; +} + +.card-header-icon { + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + padding: 0.75rem; +} + +.card-image { + display: block; + position: relative; +} + +.card-content { + background-color: transparent; + padding: 1.5rem; +} + +.card-footer { + background-color: transparent; + border-top: 1px solid #dbdbdb; + align-items: stretch; + display: flex; +} + +.card-footer-item { + align-items: center; + display: flex; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 0; + justify-content: center; + padding: 0.75rem; +} + +.card-footer-item:not(:last-child) { + border-right: 1px solid #dbdbdb; +} + +.card .media:not(:last-child) { + margin-bottom: 1.5rem; +} + +.dropdown { + display: inline-flex; + position: relative; + vertical-align: top; +} + +.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu { + display: block; +} + +.dropdown.is-right .dropdown-menu { + left: auto; + right: 0; +} + +.dropdown.is-up .dropdown-menu { + bottom: 100%; + padding-bottom: 4px; + padding-top: initial; + top: auto; +} + +.dropdown-menu { + display: none; + left: 0; + min-width: 12rem; + padding-top: 4px; + position: absolute; + top: 100%; + z-index: 20; +} + +.dropdown-content { + background-color: white; + border-radius: 4px; + box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} + +.dropdown-item { + color: #4a4a4a; + display: block; + font-size: 0.875rem; + line-height: 1.5; + padding: 0.375rem 1rem; + position: relative; +} + +a.dropdown-item, +button.dropdown-item { + padding-right: 3rem; + text-align: left; + white-space: nowrap; + width: 100%; +} + +a.dropdown-item:hover, +button.dropdown-item:hover { + background-color: whitesmoke; + color: #0a0a0a; +} + +a.dropdown-item.is-active, +button.dropdown-item.is-active { + background-color: #3273dc; + color: #fff; +} + +.dropdown-divider { + background-color: #dbdbdb; + border: none; + display: block; + height: 1px; + margin: 0.5rem 0; +} + +.level { + align-items: center; + justify-content: space-between; +} + +.level code { + border-radius: 4px; +} + +.level img { + display: inline-block; + vertical-align: top; +} + +.level.is-mobile { + display: flex; +} + +.level.is-mobile .level-left, +.level.is-mobile .level-right { + display: flex; +} + +.level.is-mobile .level-left + .level-right { + margin-top: 0; +} + +.level.is-mobile .level-item:not(:last-child) { + margin-bottom: 0; + margin-right: 0.75rem; +} + +.level.is-mobile .level-item:not(.is-narrow) { + flex-grow: 1; +} + +@media screen and (min-width: 769px), print { + .level { + display: flex; + } + .level > .level-item:not(.is-narrow) { + flex-grow: 1; + } +} + +.level-item { + align-items: center; + display: flex; + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; + justify-content: center; +} + +.level-item .title, +.level-item .subtitle { + margin-bottom: 0; +} + +@media screen and (max-width: 768px) { + .level-item:not(:last-child) { + margin-bottom: 0.75rem; + } +} + +.level-left, +.level-right { + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; +} + +.level-left .level-item.is-flexible, +.level-right .level-item.is-flexible { + flex-grow: 1; +} + +@media screen and (min-width: 769px), print { + .level-left .level-item:not(:last-child), + .level-right .level-item:not(:last-child) { + margin-right: 0.75rem; + } +} + +.level-left { + align-items: center; + justify-content: flex-start; +} + +@media screen and (max-width: 768px) { + .level-left + .level-right { + margin-top: 1.5rem; + } +} + +@media screen and (min-width: 769px), print { + .level-left { + display: flex; + } +} + +.level-right { + align-items: center; + justify-content: flex-end; +} + +@media screen and (min-width: 769px), print { + .level-right { + display: flex; + } +} + +.list { + background-color: white; + border-radius: 4px; + box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); +} + +.list-item { + display: block; + padding: 0.5em 1em; +} + +.list-item:not(a) { + color: #4a4a4a; +} + +.list-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +.list-item:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +.list-item:not(:last-child) { + border-bottom: 1px solid #dbdbdb; +} + +.list-item.is-active { + background-color: #3273dc; + color: #fff; +} + +a.list-item { + background-color: whitesmoke; + cursor: pointer; +} + +.media { + align-items: flex-start; + display: flex; + text-align: left; +} + +.media .content:not(:last-child) { + margin-bottom: 0.75rem; +} + +.media .media { + border-top: 1px solid rgba(219, 219, 219, 0.5); + display: flex; + padding-top: 0.75rem; +} + +.media .media .content:not(:last-child), +.media .media .control:not(:last-child) { + margin-bottom: 0.5rem; +} + +.media .media .media { + padding-top: 0.5rem; +} + +.media .media .media + .media { + margin-top: 0.5rem; +} + +.media + .media { + border-top: 1px solid rgba(219, 219, 219, 0.5); + margin-top: 1rem; + padding-top: 1rem; +} + +.media.is-large + .media { + margin-top: 1.5rem; + padding-top: 1.5rem; +} + +.media-left, +.media-right { + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; +} + +.media-left { + margin-right: 1rem; +} + +.media-right { + margin-left: 1rem; +} + +.media-content { + flex-basis: auto; + flex-grow: 1; + flex-shrink: 1; + text-align: left; +} + +@media screen and (max-width: 768px) { + .media-content { + overflow-x: auto; + } +} + +.menu { + font-size: 1rem; +} + +.menu.is-small { + font-size: 0.75rem; +} + +.menu.is-medium { + font-size: 1.25rem; +} + +.menu.is-large { + font-size: 1.5rem; +} + +.menu-list { + line-height: 1.25; +} + +.menu-list a { + border-radius: 2px; + color: #4a4a4a; + display: block; + padding: 0.5em 0.75em; +} + +.menu-list a:hover { + background-color: whitesmoke; + color: #363636; +} + +.menu-list a.is-active { + background-color: #3273dc; + color: #fff; +} + +.menu-list li ul { + border-left: 1px solid #dbdbdb; + margin: 0.75em; + padding-left: 0.75em; +} + +.menu-label { + color: #7a7a7a; + font-size: 0.75em; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.menu-label:not(:first-child) { + margin-top: 1em; +} + +.menu-label:not(:last-child) { + margin-bottom: 1em; +} + +.message { + background-color: whitesmoke; + border-radius: 4px; + font-size: 1rem; +} + +.message strong { + color: currentColor; +} + +.message a:not(.button):not(.tag):not(.dropdown-item) { + color: currentColor; + text-decoration: underline; +} + +.message.is-small { + font-size: 0.75rem; +} + +.message.is-medium { + font-size: 1.25rem; +} + +.message.is-large { + font-size: 1.5rem; +} + +.message.is-white { + background-color: white; +} + +.message.is-white .message-header { + background-color: white; + color: #0a0a0a; +} + +.message.is-white .message-body { + border-color: white; + color: #4d4d4d; +} + +.message.is-black { + background-color: #fafafa; +} + +.message.is-black .message-header { + background-color: #0a0a0a; + color: white; +} + +.message.is-black .message-body { + border-color: #0a0a0a; + color: #090909; +} + +.message.is-light { + background-color: #fafafa; +} + +.message.is-light .message-header { + background-color: whitesmoke; + color: #363636; +} + +.message.is-light .message-body { + border-color: whitesmoke; + color: #505050; +} + +.message.is-dark { + background-color: #fafafa; +} + +.message.is-dark .message-header { + background-color: #363636; + color: whitesmoke; +} + +.message.is-dark .message-body { + border-color: #363636; + color: #2a2a2a; +} + +.message.is-primary { + background-color: #f5fffd; +} + +.message.is-primary .message-header { + background-color: #00d1b2; + color: #fff; +} + +.message.is-primary .message-body { + border-color: #00d1b2; + color: #021310; +} + +.message.is-link { + background-color: #f6f9fe; +} + +.message.is-link .message-header { + background-color: #3273dc; + color: #fff; +} + +.message.is-link .message-body { + border-color: #3273dc; + color: #22509a; +} + +.message.is-info { + background-color: #f6fbfe; +} + +.message.is-info .message-header { + background-color: #209cee; + color: #fff; +} + +.message.is-info .message-body { + border-color: #209cee; + color: #12537e; +} + +.message.is-success { + background-color: #f6fef9; +} + +.message.is-success .message-header { + background-color: #23d160; + color: #fff; +} + +.message.is-success .message-body { + border-color: #23d160; + color: #0e301a; +} + +.message.is-warning { + background-color: #fffdf5; +} + +.message.is-warning .message-header { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.message.is-warning .message-body { + border-color: #ffdd57; + color: #3b3108; +} + +.message.is-danger { + background-color: #fff5f7; +} + +.message.is-danger .message-header { + background-color: #ff3860; + color: #fff; +} + +.message.is-danger .message-body { + border-color: #ff3860; + color: #cd0930; +} + +.message-header { + align-items: center; + background-color: #4a4a4a; + border-radius: 4px 4px 0 0; + color: #fff; + display: flex; + font-weight: 700; + justify-content: space-between; + line-height: 1.25; + padding: 0.75em 1em; + position: relative; +} + +.message-header .delete { + flex-grow: 0; + flex-shrink: 0; + margin-left: 0.75em; +} + +.message-header + .message-body { + border-width: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.message-body { + border-color: #dbdbdb; + border-radius: 4px; + border-style: solid; + border-width: 0 0 0 4px; + color: #4a4a4a; + padding: 1.25em 1.5em; +} + +.message-body code, +.message-body pre { + background-color: white; +} + +.message-body pre code { + background-color: transparent; +} + +.modal { + align-items: center; + display: none; + flex-direction: column; + justify-content: center; + overflow: hidden; + position: fixed; + z-index: 40; +} + +.modal.is-active { + display: flex; +} + +.modal-background { + background-color: rgba(10, 10, 10, 0.86); +} + +.modal-content, +.modal-card { + margin: 0 20px; + max-height: calc(100vh - 160px); + overflow: auto; + position: relative; + width: 100%; +} + +@media screen and (min-width: 769px), print { + .modal-content, + .modal-card { + margin: 0 auto; + max-height: calc(100vh - 40px); + width: 640px; + } +} + +.modal-close { + background: none; + height: 40px; + position: fixed; + right: 20px; + top: 20px; + width: 40px; +} + +.modal-card { + display: flex; + flex-direction: column; + max-height: calc(100vh - 40px); + overflow: hidden; + -ms-overflow-y: visible; +} + +.modal-card-head, +.modal-card-foot { + align-items: center; + background-color: whitesmoke; + display: flex; + flex-shrink: 0; + justify-content: flex-start; + padding: 20px; + position: relative; +} + +.modal-card-head { + border-bottom: 1px solid #dbdbdb; + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +.modal-card-title { + color: #363636; + flex-grow: 1; + flex-shrink: 0; + font-size: 1.5rem; + line-height: 1; +} + +.modal-card-foot { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-top: 1px solid #dbdbdb; +} + +.modal-card-foot .button:not(:last-child) { + margin-right: 0.5em; +} + +.modal-card-body { + -webkit-overflow-scrolling: touch; + background-color: white; + flex-grow: 1; + flex-shrink: 1; + overflow: auto; + padding: 20px; +} + +.navbar { + background-color: white; + min-height: 3.25rem; + position: relative; + z-index: 30; +} + +.navbar.is-white { + background-color: white; + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand > .navbar-item, +.navbar.is-white .navbar-brand .navbar-link { + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand > a.navbar-item:focus, .navbar.is-white .navbar-brand > a.navbar-item:hover, .navbar.is-white .navbar-brand > a.navbar-item.is-active, +.navbar.is-white .navbar-brand .navbar-link:focus, +.navbar.is-white .navbar-brand .navbar-link:hover, +.navbar.is-white .navbar-brand .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand .navbar-link::after { + border-color: #0a0a0a; +} + +.navbar.is-white .navbar-burger { + color: #0a0a0a; +} + +@media screen and (min-width: 1024px) { + .navbar.is-white .navbar-start > .navbar-item, + .navbar.is-white .navbar-start .navbar-link, + .navbar.is-white .navbar-end > .navbar-item, + .navbar.is-white .navbar-end .navbar-link { + color: #0a0a0a; + } + .navbar.is-white .navbar-start > a.navbar-item:focus, .navbar.is-white .navbar-start > a.navbar-item:hover, .navbar.is-white .navbar-start > a.navbar-item.is-active, + .navbar.is-white .navbar-start .navbar-link:focus, + .navbar.is-white .navbar-start .navbar-link:hover, + .navbar.is-white .navbar-start .navbar-link.is-active, + .navbar.is-white .navbar-end > a.navbar-item:focus, + .navbar.is-white .navbar-end > a.navbar-item:hover, + .navbar.is-white .navbar-end > a.navbar-item.is-active, + .navbar.is-white .navbar-end .navbar-link:focus, + .navbar.is-white .navbar-end .navbar-link:hover, + .navbar.is-white .navbar-end .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; + } + .navbar.is-white .navbar-start .navbar-link::after, + .navbar.is-white .navbar-end .navbar-link::after { + border-color: #0a0a0a; + } + .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #f2f2f2; + color: #0a0a0a; + } + .navbar.is-white .navbar-dropdown a.navbar-item.is-active { + background-color: white; + color: #0a0a0a; + } +} + +.navbar.is-black { + background-color: #0a0a0a; + color: white; +} + +.navbar.is-black .navbar-brand > .navbar-item, +.navbar.is-black .navbar-brand .navbar-link { + color: white; +} + +.navbar.is-black .navbar-brand > a.navbar-item:focus, .navbar.is-black .navbar-brand > a.navbar-item:hover, .navbar.is-black .navbar-brand > a.navbar-item.is-active, +.navbar.is-black .navbar-brand .navbar-link:focus, +.navbar.is-black .navbar-brand .navbar-link:hover, +.navbar.is-black .navbar-brand .navbar-link.is-active { + background-color: black; + color: white; +} + +.navbar.is-black .navbar-brand .navbar-link::after { + border-color: white; +} + +.navbar.is-black .navbar-burger { + color: white; +} + +@media screen and (min-width: 1024px) { + .navbar.is-black .navbar-start > .navbar-item, + .navbar.is-black .navbar-start .navbar-link, + .navbar.is-black .navbar-end > .navbar-item, + .navbar.is-black .navbar-end .navbar-link { + color: white; + } + .navbar.is-black .navbar-start > a.navbar-item:focus, .navbar.is-black .navbar-start > a.navbar-item:hover, .navbar.is-black .navbar-start > a.navbar-item.is-active, + .navbar.is-black .navbar-start .navbar-link:focus, + .navbar.is-black .navbar-start .navbar-link:hover, + .navbar.is-black .navbar-start .navbar-link.is-active, + .navbar.is-black .navbar-end > a.navbar-item:focus, + .navbar.is-black .navbar-end > a.navbar-item:hover, + .navbar.is-black .navbar-end > a.navbar-item.is-active, + .navbar.is-black .navbar-end .navbar-link:focus, + .navbar.is-black .navbar-end .navbar-link:hover, + .navbar.is-black .navbar-end .navbar-link.is-active { + background-color: black; + color: white; + } + .navbar.is-black .navbar-start .navbar-link::after, + .navbar.is-black .navbar-end .navbar-link::after { + border-color: white; + } + .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link { + background-color: black; + color: white; + } + .navbar.is-black .navbar-dropdown a.navbar-item.is-active { + background-color: #0a0a0a; + color: white; + } +} + +.navbar.is-light { + background-color: whitesmoke; + color: #363636; +} + +.navbar.is-light .navbar-brand > .navbar-item, +.navbar.is-light .navbar-brand .navbar-link { + color: #363636; +} + +.navbar.is-light .navbar-brand > a.navbar-item:focus, .navbar.is-light .navbar-brand > a.navbar-item:hover, .navbar.is-light .navbar-brand > a.navbar-item.is-active, +.navbar.is-light .navbar-brand .navbar-link:focus, +.navbar.is-light .navbar-brand .navbar-link:hover, +.navbar.is-light .navbar-brand .navbar-link.is-active { + background-color: #e8e8e8; + color: #363636; +} + +.navbar.is-light .navbar-brand .navbar-link::after { + border-color: #363636; +} + +.navbar.is-light .navbar-burger { + color: #363636; +} + +@media screen and (min-width: 1024px) { + .navbar.is-light .navbar-start > .navbar-item, + .navbar.is-light .navbar-start .navbar-link, + .navbar.is-light .navbar-end > .navbar-item, + .navbar.is-light .navbar-end .navbar-link { + color: #363636; + } + .navbar.is-light .navbar-start > a.navbar-item:focus, .navbar.is-light .navbar-start > a.navbar-item:hover, .navbar.is-light .navbar-start > a.navbar-item.is-active, + .navbar.is-light .navbar-start .navbar-link:focus, + .navbar.is-light .navbar-start .navbar-link:hover, + .navbar.is-light .navbar-start .navbar-link.is-active, + .navbar.is-light .navbar-end > a.navbar-item:focus, + .navbar.is-light .navbar-end > a.navbar-item:hover, + .navbar.is-light .navbar-end > a.navbar-item.is-active, + .navbar.is-light .navbar-end .navbar-link:focus, + .navbar.is-light .navbar-end .navbar-link:hover, + .navbar.is-light .navbar-end .navbar-link.is-active { + background-color: #e8e8e8; + color: #363636; + } + .navbar.is-light .navbar-start .navbar-link::after, + .navbar.is-light .navbar-end .navbar-link::after { + border-color: #363636; + } + .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #e8e8e8; + color: #363636; + } + .navbar.is-light .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: #363636; + } +} + +.navbar.is-dark { + background-color: #363636; + color: whitesmoke; +} + +.navbar.is-dark .navbar-brand > .navbar-item, +.navbar.is-dark .navbar-brand .navbar-link { + color: whitesmoke; +} + +.navbar.is-dark .navbar-brand > a.navbar-item:focus, .navbar.is-dark .navbar-brand > a.navbar-item:hover, .navbar.is-dark .navbar-brand > a.navbar-item.is-active, +.navbar.is-dark .navbar-brand .navbar-link:focus, +.navbar.is-dark .navbar-brand .navbar-link:hover, +.navbar.is-dark .navbar-brand .navbar-link.is-active { + background-color: #292929; + color: whitesmoke; +} + +.navbar.is-dark .navbar-brand .navbar-link::after { + border-color: whitesmoke; +} + +.navbar.is-dark .navbar-burger { + color: whitesmoke; +} + +@media screen and (min-width: 1024px) { + .navbar.is-dark .navbar-start > .navbar-item, + .navbar.is-dark .navbar-start .navbar-link, + .navbar.is-dark .navbar-end > .navbar-item, + .navbar.is-dark .navbar-end .navbar-link { + color: whitesmoke; + } + .navbar.is-dark .navbar-start > a.navbar-item:focus, .navbar.is-dark .navbar-start > a.navbar-item:hover, .navbar.is-dark .navbar-start > a.navbar-item.is-active, + .navbar.is-dark .navbar-start .navbar-link:focus, + .navbar.is-dark .navbar-start .navbar-link:hover, + .navbar.is-dark .navbar-start .navbar-link.is-active, + .navbar.is-dark .navbar-end > a.navbar-item:focus, + .navbar.is-dark .navbar-end > a.navbar-item:hover, + .navbar.is-dark .navbar-end > a.navbar-item.is-active, + .navbar.is-dark .navbar-end .navbar-link:focus, + .navbar.is-dark .navbar-end .navbar-link:hover, + .navbar.is-dark .navbar-end .navbar-link.is-active { + background-color: #292929; + color: whitesmoke; + } + .navbar.is-dark .navbar-start .navbar-link::after, + .navbar.is-dark .navbar-end .navbar-link::after { + border-color: whitesmoke; + } + .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #292929; + color: whitesmoke; + } + .navbar.is-dark .navbar-dropdown a.navbar-item.is-active { + background-color: #363636; + color: whitesmoke; + } +} + +.navbar.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.navbar.is-primary .navbar-brand > .navbar-item, +.navbar.is-primary .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-primary .navbar-brand > a.navbar-item:focus, .navbar.is-primary .navbar-brand > a.navbar-item:hover, .navbar.is-primary .navbar-brand > a.navbar-item.is-active, +.navbar.is-primary .navbar-brand .navbar-link:focus, +.navbar.is-primary .navbar-brand .navbar-link:hover, +.navbar.is-primary .navbar-brand .navbar-link.is-active { + background-color: #00b89c; + color: #fff; +} + +.navbar.is-primary .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-primary .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-primary .navbar-start > .navbar-item, + .navbar.is-primary .navbar-start .navbar-link, + .navbar.is-primary .navbar-end > .navbar-item, + .navbar.is-primary .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-primary .navbar-start > a.navbar-item:focus, .navbar.is-primary .navbar-start > a.navbar-item:hover, .navbar.is-primary .navbar-start > a.navbar-item.is-active, + .navbar.is-primary .navbar-start .navbar-link:focus, + .navbar.is-primary .navbar-start .navbar-link:hover, + .navbar.is-primary .navbar-start .navbar-link.is-active, + .navbar.is-primary .navbar-end > a.navbar-item:focus, + .navbar.is-primary .navbar-end > a.navbar-item:hover, + .navbar.is-primary .navbar-end > a.navbar-item.is-active, + .navbar.is-primary .navbar-end .navbar-link:focus, + .navbar.is-primary .navbar-end .navbar-link:hover, + .navbar.is-primary .navbar-end .navbar-link.is-active { + background-color: #00b89c; + color: #fff; + } + .navbar.is-primary .navbar-start .navbar-link::after, + .navbar.is-primary .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #00b89c; + color: #fff; + } + .navbar.is-primary .navbar-dropdown a.navbar-item.is-active { + background-color: #00d1b2; + color: #fff; + } +} + +.navbar.is-link { + background-color: #3273dc; + color: #fff; +} + +.navbar.is-link .navbar-brand > .navbar-item, +.navbar.is-link .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-link .navbar-brand > a.navbar-item:focus, .navbar.is-link .navbar-brand > a.navbar-item:hover, .navbar.is-link .navbar-brand > a.navbar-item.is-active, +.navbar.is-link .navbar-brand .navbar-link:focus, +.navbar.is-link .navbar-brand .navbar-link:hover, +.navbar.is-link .navbar-brand .navbar-link.is-active { + background-color: #2366d1; + color: #fff; +} + +.navbar.is-link .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-link .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-link .navbar-start > .navbar-item, + .navbar.is-link .navbar-start .navbar-link, + .navbar.is-link .navbar-end > .navbar-item, + .navbar.is-link .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-link .navbar-start > a.navbar-item:focus, .navbar.is-link .navbar-start > a.navbar-item:hover, .navbar.is-link .navbar-start > a.navbar-item.is-active, + .navbar.is-link .navbar-start .navbar-link:focus, + .navbar.is-link .navbar-start .navbar-link:hover, + .navbar.is-link .navbar-start .navbar-link.is-active, + .navbar.is-link .navbar-end > a.navbar-item:focus, + .navbar.is-link .navbar-end > a.navbar-item:hover, + .navbar.is-link .navbar-end > a.navbar-item.is-active, + .navbar.is-link .navbar-end .navbar-link:focus, + .navbar.is-link .navbar-end .navbar-link:hover, + .navbar.is-link .navbar-end .navbar-link.is-active { + background-color: #2366d1; + color: #fff; + } + .navbar.is-link .navbar-start .navbar-link::after, + .navbar.is-link .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #2366d1; + color: #fff; + } + .navbar.is-link .navbar-dropdown a.navbar-item.is-active { + background-color: #3273dc; + color: #fff; + } +} + +.navbar.is-info { + background-color: #209cee; + color: #fff; +} + +.navbar.is-info .navbar-brand > .navbar-item, +.navbar.is-info .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-info .navbar-brand > a.navbar-item:focus, .navbar.is-info .navbar-brand > a.navbar-item:hover, .navbar.is-info .navbar-brand > a.navbar-item.is-active, +.navbar.is-info .navbar-brand .navbar-link:focus, +.navbar.is-info .navbar-brand .navbar-link:hover, +.navbar.is-info .navbar-brand .navbar-link.is-active { + background-color: #118fe4; + color: #fff; +} + +.navbar.is-info .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-info .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-info .navbar-start > .navbar-item, + .navbar.is-info .navbar-start .navbar-link, + .navbar.is-info .navbar-end > .navbar-item, + .navbar.is-info .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-info .navbar-start > a.navbar-item:focus, .navbar.is-info .navbar-start > a.navbar-item:hover, .navbar.is-info .navbar-start > a.navbar-item.is-active, + .navbar.is-info .navbar-start .navbar-link:focus, + .navbar.is-info .navbar-start .navbar-link:hover, + .navbar.is-info .navbar-start .navbar-link.is-active, + .navbar.is-info .navbar-end > a.navbar-item:focus, + .navbar.is-info .navbar-end > a.navbar-item:hover, + .navbar.is-info .navbar-end > a.navbar-item.is-active, + .navbar.is-info .navbar-end .navbar-link:focus, + .navbar.is-info .navbar-end .navbar-link:hover, + .navbar.is-info .navbar-end .navbar-link.is-active { + background-color: #118fe4; + color: #fff; + } + .navbar.is-info .navbar-start .navbar-link::after, + .navbar.is-info .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #118fe4; + color: #fff; + } + .navbar.is-info .navbar-dropdown a.navbar-item.is-active { + background-color: #209cee; + color: #fff; + } +} + +.navbar.is-success { + background-color: #23d160; + color: #fff; +} + +.navbar.is-success .navbar-brand > .navbar-item, +.navbar.is-success .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-success .navbar-brand > a.navbar-item:focus, .navbar.is-success .navbar-brand > a.navbar-item:hover, .navbar.is-success .navbar-brand > a.navbar-item.is-active, +.navbar.is-success .navbar-brand .navbar-link:focus, +.navbar.is-success .navbar-brand .navbar-link:hover, +.navbar.is-success .navbar-brand .navbar-link.is-active { + background-color: #20bc56; + color: #fff; +} + +.navbar.is-success .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-success .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-success .navbar-start > .navbar-item, + .navbar.is-success .navbar-start .navbar-link, + .navbar.is-success .navbar-end > .navbar-item, + .navbar.is-success .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-success .navbar-start > a.navbar-item:focus, .navbar.is-success .navbar-start > a.navbar-item:hover, .navbar.is-success .navbar-start > a.navbar-item.is-active, + .navbar.is-success .navbar-start .navbar-link:focus, + .navbar.is-success .navbar-start .navbar-link:hover, + .navbar.is-success .navbar-start .navbar-link.is-active, + .navbar.is-success .navbar-end > a.navbar-item:focus, + .navbar.is-success .navbar-end > a.navbar-item:hover, + .navbar.is-success .navbar-end > a.navbar-item.is-active, + .navbar.is-success .navbar-end .navbar-link:focus, + .navbar.is-success .navbar-end .navbar-link:hover, + .navbar.is-success .navbar-end .navbar-link.is-active { + background-color: #20bc56; + color: #fff; + } + .navbar.is-success .navbar-start .navbar-link::after, + .navbar.is-success .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #20bc56; + color: #fff; + } + .navbar.is-success .navbar-dropdown a.navbar-item.is-active { + background-color: #23d160; + color: #fff; + } +} + +.navbar.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand > .navbar-item, +.navbar.is-warning .navbar-brand .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand > a.navbar-item:focus, .navbar.is-warning .navbar-brand > a.navbar-item:hover, .navbar.is-warning .navbar-brand > a.navbar-item.is-active, +.navbar.is-warning .navbar-brand .navbar-link:focus, +.navbar.is-warning .navbar-brand .navbar-link:hover, +.navbar.is-warning .navbar-brand .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-burger { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (min-width: 1024px) { + .navbar.is-warning .navbar-start > .navbar-item, + .navbar.is-warning .navbar-start .navbar-link, + .navbar.is-warning .navbar-end > .navbar-item, + .navbar.is-warning .navbar-end .navbar-link { + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-start > a.navbar-item:focus, .navbar.is-warning .navbar-start > a.navbar-item:hover, .navbar.is-warning .navbar-start > a.navbar-item.is-active, + .navbar.is-warning .navbar-start .navbar-link:focus, + .navbar.is-warning .navbar-start .navbar-link:hover, + .navbar.is-warning .navbar-start .navbar-link.is-active, + .navbar.is-warning .navbar-end > a.navbar-item:focus, + .navbar.is-warning .navbar-end > a.navbar-item:hover, + .navbar.is-warning .navbar-end > a.navbar-item.is-active, + .navbar.is-warning .navbar-end .navbar-link:focus, + .navbar.is-warning .navbar-end .navbar-link:hover, + .navbar.is-warning .navbar-end .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-start .navbar-link::after, + .navbar.is-warning .navbar-end .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-dropdown a.navbar-item.is-active { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); + } +} + +.navbar.is-danger { + background-color: #ff3860; + color: #fff; +} + +.navbar.is-danger .navbar-brand > .navbar-item, +.navbar.is-danger .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-danger .navbar-brand > a.navbar-item:focus, .navbar.is-danger .navbar-brand > a.navbar-item:hover, .navbar.is-danger .navbar-brand > a.navbar-item.is-active, +.navbar.is-danger .navbar-brand .navbar-link:focus, +.navbar.is-danger .navbar-brand .navbar-link:hover, +.navbar.is-danger .navbar-brand .navbar-link.is-active { + background-color: #ff1f4b; + color: #fff; +} + +.navbar.is-danger .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-danger .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-danger .navbar-start > .navbar-item, + .navbar.is-danger .navbar-start .navbar-link, + .navbar.is-danger .navbar-end > .navbar-item, + .navbar.is-danger .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-danger .navbar-start > a.navbar-item:focus, .navbar.is-danger .navbar-start > a.navbar-item:hover, .navbar.is-danger .navbar-start > a.navbar-item.is-active, + .navbar.is-danger .navbar-start .navbar-link:focus, + .navbar.is-danger .navbar-start .navbar-link:hover, + .navbar.is-danger .navbar-start .navbar-link.is-active, + .navbar.is-danger .navbar-end > a.navbar-item:focus, + .navbar.is-danger .navbar-end > a.navbar-item:hover, + .navbar.is-danger .navbar-end > a.navbar-item.is-active, + .navbar.is-danger .navbar-end .navbar-link:focus, + .navbar.is-danger .navbar-end .navbar-link:hover, + .navbar.is-danger .navbar-end .navbar-link.is-active { + background-color: #ff1f4b; + color: #fff; + } + .navbar.is-danger .navbar-start .navbar-link::after, + .navbar.is-danger .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #ff1f4b; + color: #fff; + } + .navbar.is-danger .navbar-dropdown a.navbar-item.is-active { + background-color: #ff3860; + color: #fff; + } +} + +.navbar > .container { + align-items: stretch; + display: flex; + min-height: 3.25rem; + width: 100%; +} + +.navbar.has-shadow { + box-shadow: 0 2px 0 0 whitesmoke; +} + +.navbar.is-fixed-bottom, .navbar.is-fixed-top { + left: 0; + position: fixed; + right: 0; + z-index: 30; +} + +.navbar.is-fixed-bottom { + bottom: 0; +} + +.navbar.is-fixed-bottom.has-shadow { + box-shadow: 0 -2px 0 0 whitesmoke; +} + +.navbar.is-fixed-top { + top: 0; +} + +html.has-navbar-fixed-top, +body.has-navbar-fixed-top { + padding-top: 3.25rem; +} + +html.has-navbar-fixed-bottom, +body.has-navbar-fixed-bottom { + padding-bottom: 3.25rem; +} + +.navbar-brand, +.navbar-tabs { + align-items: stretch; + display: flex; + flex-shrink: 0; + min-height: 3.25rem; +} + +.navbar-brand a.navbar-item:focus, .navbar-brand a.navbar-item:hover { + background-color: transparent; +} + +.navbar-tabs { + -webkit-overflow-scrolling: touch; + max-width: 100vw; + overflow-x: auto; + overflow-y: hidden; +} + +.navbar-burger { + color: #4a4a4a; + cursor: pointer; + display: block; + height: 3.25rem; + position: relative; + width: 3.25rem; + margin-left: auto; +} + +.navbar-burger span { + background-color: currentColor; + display: block; + height: 1px; + left: calc(50% - 8px); + position: absolute; + -webkit-transform-origin: center; + transform-origin: center; + transition-duration: 86ms; + transition-property: background-color, opacity, -webkit-transform; + transition-property: background-color, opacity, transform; + transition-property: background-color, opacity, transform, -webkit-transform; + transition-timing-function: ease-out; + width: 16px; +} + +.navbar-burger span:nth-child(1) { + top: calc(50% - 6px); +} + +.navbar-burger span:nth-child(2) { + top: calc(50% - 1px); +} + +.navbar-burger span:nth-child(3) { + top: calc(50% + 4px); +} + +.navbar-burger:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +.navbar-burger.is-active span:nth-child(1) { + -webkit-transform: translateY(5px) rotate(45deg); + transform: translateY(5px) rotate(45deg); +} + +.navbar-burger.is-active span:nth-child(2) { + opacity: 0; +} + +.navbar-burger.is-active span:nth-child(3) { + -webkit-transform: translateY(-5px) rotate(-45deg); + transform: translateY(-5px) rotate(-45deg); +} + +.navbar-menu { + display: none; +} + +.navbar-item, +.navbar-link { + color: #4a4a4a; + display: block; + line-height: 1.5; + padding: 0.5rem 0.75rem; + position: relative; +} + +.navbar-item .icon:only-child, +.navbar-link .icon:only-child { + margin-left: -0.25rem; + margin-right: -0.25rem; +} + +a.navbar-item, +.navbar-link { + cursor: pointer; +} + +a.navbar-item:focus, a.navbar-item:focus-within, a.navbar-item:hover, a.navbar-item.is-active, +.navbar-link:focus, +.navbar-link:focus-within, +.navbar-link:hover, +.navbar-link.is-active { + background-color: #fafafa; + color: #3273dc; +} + +.navbar-item { + display: block; + flex-grow: 0; + flex-shrink: 0; +} + +.navbar-item img { + max-height: 1.75rem; +} + +.navbar-item.has-dropdown { + padding: 0; +} + +.navbar-item.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.navbar-item.is-tab { + border-bottom: 1px solid transparent; + min-height: 3.25rem; + padding-bottom: calc(0.5rem - 1px); +} + +.navbar-item.is-tab:focus, .navbar-item.is-tab:hover { + background-color: transparent; + border-bottom-color: #3273dc; +} + +.navbar-item.is-tab.is-active { + background-color: transparent; + border-bottom-color: #3273dc; + border-bottom-style: solid; + border-bottom-width: 3px; + color: #3273dc; + padding-bottom: calc(0.5rem - 3px); +} + +.navbar-content { + flex-grow: 1; + flex-shrink: 1; +} + +.navbar-link:not(.is-arrowless) { + padding-right: 2.5em; +} + +.navbar-link:not(.is-arrowless)::after { + border-color: #3273dc; + margin-top: -0.375em; + right: 1.125em; +} + +.navbar-dropdown { + font-size: 0.875rem; + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} + +.navbar-dropdown .navbar-item { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.navbar-divider { + background-color: whitesmoke; + border: none; + display: none; + height: 2px; + margin: 0.5rem 0; +} + +@media screen and (max-width: 1023px) { + .navbar > .container { + display: block; + } + .navbar-brand .navbar-item, + .navbar-tabs .navbar-item { + align-items: center; + display: flex; + } + .navbar-link::after { + display: none; + } + .navbar-menu { + background-color: white; + box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1); + padding: 0.5rem 0; + } + .navbar-menu.is-active { + display: block; + } + .navbar.is-fixed-bottom-touch, .navbar.is-fixed-top-touch { + left: 0; + position: fixed; + right: 0; + z-index: 30; + } + .navbar.is-fixed-bottom-touch { + bottom: 0; + } + .navbar.is-fixed-bottom-touch.has-shadow { + box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1); + } + .navbar.is-fixed-top-touch { + top: 0; + } + .navbar.is-fixed-top .navbar-menu, .navbar.is-fixed-top-touch .navbar-menu { + -webkit-overflow-scrolling: touch; + max-height: calc(100vh - 3.25rem); + overflow: auto; + } + html.has-navbar-fixed-top-touch, + body.has-navbar-fixed-top-touch { + padding-top: 3.25rem; + } + html.has-navbar-fixed-bottom-touch, + body.has-navbar-fixed-bottom-touch { + padding-bottom: 3.25rem; + } +} + +@media screen and (min-width: 1024px) { + .navbar, + .navbar-menu, + .navbar-start, + .navbar-end { + align-items: stretch; + display: flex; + } + .navbar { + min-height: 3.25rem; + } + .navbar.is-spaced { + padding: 1rem 2rem; + } + .navbar.is-spaced .navbar-start, + .navbar.is-spaced .navbar-end { + align-items: center; + } + .navbar.is-spaced a.navbar-item, + .navbar.is-spaced .navbar-link { + border-radius: 4px; + } + .navbar.is-transparent a.navbar-item:focus, .navbar.is-transparent a.navbar-item:hover, .navbar.is-transparent a.navbar-item.is-active, + .navbar.is-transparent .navbar-link:focus, + .navbar.is-transparent .navbar-link:hover, + .navbar.is-transparent .navbar-link.is-active { + background-color: transparent !important; + } + .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link { + background-color: transparent !important; + } + .navbar.is-transparent .navbar-dropdown a.navbar-item:focus, .navbar.is-transparent .navbar-dropdown a.navbar-item:hover { + background-color: whitesmoke; + color: #0a0a0a; + } + .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: #3273dc; + } + .navbar-burger { + display: none; + } + .navbar-item, + .navbar-link { + align-items: center; + display: flex; + } + .navbar-item { + display: flex; + } + .navbar-item.has-dropdown { + align-items: stretch; + } + .navbar-item.has-dropdown-up .navbar-link::after { + -webkit-transform: rotate(135deg) translate(0.25em, -0.25em); + transform: rotate(135deg) translate(0.25em, -0.25em); + } + .navbar-item.has-dropdown-up .navbar-dropdown { + border-bottom: 2px solid #dbdbdb; + border-radius: 6px 6px 0 0; + border-top: none; + bottom: 100%; + box-shadow: 0 -8px 8px rgba(10, 10, 10, 0.1); + top: auto; + } + .navbar-item.is-active .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown { + display: block; + } + .navbar.is-spaced .navbar-item.is-active .navbar-dropdown, .navbar-item.is-active .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed { + opacity: 1; + pointer-events: auto; + -webkit-transform: translateY(0); + transform: translateY(0); + } + .navbar-menu { + flex-grow: 1; + flex-shrink: 0; + } + .navbar-start { + justify-content: flex-start; + margin-right: auto; + } + .navbar-end { + justify-content: flex-end; + margin-left: auto; + } + .navbar-dropdown { + background-color: white; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-top: 2px solid #dbdbdb; + box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1); + display: none; + font-size: 0.875rem; + left: 0; + min-width: 100%; + position: absolute; + top: 100%; + z-index: 20; + } + .navbar-dropdown .navbar-item { + padding: 0.375rem 1rem; + white-space: nowrap; + } + .navbar-dropdown a.navbar-item { + padding-right: 3rem; + } + .navbar-dropdown a.navbar-item:focus, .navbar-dropdown a.navbar-item:hover { + background-color: whitesmoke; + color: #0a0a0a; + } + .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: #3273dc; + } + .navbar.is-spaced .navbar-dropdown, .navbar-dropdown.is-boxed { + border-radius: 6px; + border-top: none; + box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); + display: block; + opacity: 0; + pointer-events: none; + top: calc(100% + (-4px)); + -webkit-transform: translateY(-5px); + transform: translateY(-5px); + transition-duration: 86ms; + transition-property: opacity, -webkit-transform; + transition-property: opacity, transform; + transition-property: opacity, transform, -webkit-transform; + } + .navbar-dropdown.is-right { + left: auto; + right: 0; + } + .navbar-divider { + display: block; + } + .navbar > .container .navbar-brand, + .container > .navbar .navbar-brand { + margin-left: -.75rem; + } + .navbar > .container .navbar-menu, + .container > .navbar .navbar-menu { + margin-right: -.75rem; + } + .navbar.is-fixed-bottom-desktop, .navbar.is-fixed-top-desktop { + left: 0; + position: fixed; + right: 0; + z-index: 30; + } + .navbar.is-fixed-bottom-desktop { + bottom: 0; + } + .navbar.is-fixed-bottom-desktop.has-shadow { + box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1); + } + .navbar.is-fixed-top-desktop { + top: 0; + } + html.has-navbar-fixed-top-desktop, + body.has-navbar-fixed-top-desktop { + padding-top: 3.25rem; + } + html.has-navbar-fixed-bottom-desktop, + body.has-navbar-fixed-bottom-desktop { + padding-bottom: 3.25rem; + } + html.has-spaced-navbar-fixed-top, + body.has-spaced-navbar-fixed-top { + padding-top: 5.25rem; + } + html.has-spaced-navbar-fixed-bottom, + body.has-spaced-navbar-fixed-bottom { + padding-bottom: 5.25rem; + } + a.navbar-item.is-active, + .navbar-link.is-active { + color: #0a0a0a; + } + a.navbar-item.is-active:not(:focus):not(:hover), + .navbar-link.is-active:not(:focus):not(:hover) { + background-color: transparent; + } + .navbar-item.has-dropdown:focus .navbar-link, .navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #fafafa; + } +} + +.hero.is-fullheight-with-navbar { + min-height: calc(100vh - 3.25rem); +} + +.pagination { + font-size: 1rem; + margin: -0.25rem; +} + +.pagination.is-small { + font-size: 0.75rem; +} + +.pagination.is-medium { + font-size: 1.25rem; +} + +.pagination.is-large { + font-size: 1.5rem; +} + +.pagination.is-rounded .pagination-previous, +.pagination.is-rounded .pagination-next { + padding-left: 1em; + padding-right: 1em; + border-radius: 290486px; +} + +.pagination.is-rounded .pagination-link { + border-radius: 290486px; +} + +.pagination, +.pagination-list { + align-items: center; + display: flex; + justify-content: center; + text-align: center; +} + +.pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis { + font-size: 1em; + justify-content: center; + margin: 0.25rem; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: center; +} + +.pagination-previous, +.pagination-next, +.pagination-link { + border-color: #dbdbdb; + color: #363636; + min-width: 2.25em; +} + +.pagination-previous:hover, +.pagination-next:hover, +.pagination-link:hover { + border-color: #b5b5b5; + color: #363636; +} + +.pagination-previous:focus, +.pagination-next:focus, +.pagination-link:focus { + border-color: #3273dc; +} + +.pagination-previous:active, +.pagination-next:active, +.pagination-link:active { + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2); +} + +.pagination-previous[disabled], +.pagination-next[disabled], +.pagination-link[disabled] { + background-color: #dbdbdb; + border-color: #dbdbdb; + box-shadow: none; + color: #7a7a7a; + opacity: 0.5; +} + +.pagination-previous, +.pagination-next { + padding-left: 0.75em; + padding-right: 0.75em; + white-space: nowrap; +} + +.pagination-link.is-current { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.pagination-ellipsis { + color: #b5b5b5; + pointer-events: none; +} + +.pagination-list { + flex-wrap: wrap; +} + +@media screen and (max-width: 768px) { + .pagination { + flex-wrap: wrap; + } + .pagination-previous, + .pagination-next { + flex-grow: 1; + flex-shrink: 1; + } + .pagination-list li { + flex-grow: 1; + flex-shrink: 1; + } +} + +@media screen and (min-width: 769px), print { + .pagination-list { + flex-grow: 1; + flex-shrink: 1; + justify-content: flex-start; + order: 1; + } + .pagination-previous { + order: 2; + } + .pagination-next { + order: 3; + } + .pagination { + justify-content: space-between; + } + .pagination.is-centered .pagination-previous { + order: 1; + } + .pagination.is-centered .pagination-list { + justify-content: center; + order: 2; + } + .pagination.is-centered .pagination-next { + order: 3; + } + .pagination.is-right .pagination-previous { + order: 1; + } + .pagination.is-right .pagination-next { + order: 2; + } + .pagination.is-right .pagination-list { + justify-content: flex-end; + order: 3; + } +} + +.panel { + font-size: 1rem; +} + +.panel:not(:last-child) { + margin-bottom: 1.5rem; +} + +.panel-heading, +.panel-tabs, +.panel-block { + border-bottom: 1px solid #dbdbdb; + border-left: 1px solid #dbdbdb; + border-right: 1px solid #dbdbdb; +} + +.panel-heading:first-child, +.panel-tabs:first-child, +.panel-block:first-child { + border-top: 1px solid #dbdbdb; +} + +.panel-heading { + background-color: whitesmoke; + border-radius: 4px 4px 0 0; + color: #363636; + font-size: 1.25em; + font-weight: 300; + line-height: 1.25; + padding: 0.5em 0.75em; +} + +.panel-tabs { + align-items: flex-end; + display: flex; + font-size: 0.875em; + justify-content: center; +} + +.panel-tabs a { + border-bottom: 1px solid #dbdbdb; + margin-bottom: -1px; + padding: 0.5em; +} + +.panel-tabs a.is-active { + border-bottom-color: #4a4a4a; + color: #363636; +} + +.panel-list a { + color: #4a4a4a; +} + +.panel-list a:hover { + color: #3273dc; +} + +.panel-block { + align-items: center; + color: #363636; + display: flex; + justify-content: flex-start; + padding: 0.5em 0.75em; +} + +.panel-block input[type="checkbox"] { + margin-right: 0.75em; +} + +.panel-block > .control { + flex-grow: 1; + flex-shrink: 1; + width: 100%; +} + +.panel-block.is-wrapped { + flex-wrap: wrap; +} + +.panel-block.is-active { + border-left-color: #3273dc; + color: #363636; +} + +.panel-block.is-active .panel-icon { + color: #3273dc; +} + +a.panel-block, +label.panel-block { + cursor: pointer; +} + +a.panel-block:hover, +label.panel-block:hover { + background-color: whitesmoke; +} + +.panel-icon { + display: inline-block; + font-size: 14px; + height: 1em; + line-height: 1em; + text-align: center; + vertical-align: top; + width: 1em; + color: #7a7a7a; + margin-right: 0.75em; +} + +.panel-icon .fa { + font-size: inherit; + line-height: inherit; +} + +.tabs { + -webkit-overflow-scrolling: touch; + align-items: stretch; + display: flex; + font-size: 1rem; + justify-content: space-between; + overflow: hidden; + overflow-x: auto; + white-space: nowrap; +} + +.tabs a { + align-items: center; + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + color: #4a4a4a; + display: flex; + justify-content: center; + margin-bottom: -1px; + padding: 0.5em 1em; + vertical-align: top; +} + +.tabs a:hover { + border-bottom-color: #363636; + color: #363636; +} + +.tabs li { + display: block; +} + +.tabs li.is-active a { + border-bottom-color: #3273dc; + color: #3273dc; +} + +.tabs ul { + align-items: center; + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + display: flex; + flex-grow: 1; + flex-shrink: 0; + justify-content: flex-start; +} + +.tabs ul.is-left { + padding-right: 0.75em; +} + +.tabs ul.is-center { + flex: none; + justify-content: center; + padding-left: 0.75em; + padding-right: 0.75em; +} + +.tabs ul.is-right { + justify-content: flex-end; + padding-left: 0.75em; +} + +.tabs .icon:first-child { + margin-right: 0.5em; +} + +.tabs .icon:last-child { + margin-left: 0.5em; +} + +.tabs.is-centered ul { + justify-content: center; +} + +.tabs.is-right ul { + justify-content: flex-end; +} + +.tabs.is-boxed a { + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.tabs.is-boxed a:hover { + background-color: whitesmoke; + border-bottom-color: #dbdbdb; +} + +.tabs.is-boxed li.is-active a { + background-color: white; + border-color: #dbdbdb; + border-bottom-color: transparent !important; +} + +.tabs.is-fullwidth li { + flex-grow: 1; + flex-shrink: 0; +} + +.tabs.is-toggle a { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px; + margin-bottom: 0; + position: relative; +} + +.tabs.is-toggle a:hover { + background-color: whitesmoke; + border-color: #b5b5b5; + z-index: 2; +} + +.tabs.is-toggle li + li { + margin-left: -1px; +} + +.tabs.is-toggle li:first-child a { + border-radius: 4px 0 0 4px; +} + +.tabs.is-toggle li:last-child a { + border-radius: 0 4px 4px 0; +} + +.tabs.is-toggle li.is-active a { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; + z-index: 1; +} + +.tabs.is-toggle ul { + border-bottom: none; +} + +.tabs.is-toggle.is-toggle-rounded li:first-child a { + border-bottom-left-radius: 290486px; + border-top-left-radius: 290486px; + padding-left: 1.25em; +} + +.tabs.is-toggle.is-toggle-rounded li:last-child a { + border-bottom-right-radius: 290486px; + border-top-right-radius: 290486px; + padding-right: 1.25em; +} + +.tabs.is-small { + font-size: 0.75rem; +} + +.tabs.is-medium { + font-size: 1.25rem; +} + +.tabs.is-large { + font-size: 1.5rem; +} + +.column { + display: block; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 1; + padding: 0.75rem; +} + +.columns.is-mobile > .column.is-narrow { + flex: none; +} + +.columns.is-mobile > .column.is-full { + flex: none; + width: 100%; +} + +.columns.is-mobile > .column.is-three-quarters { + flex: none; + width: 75%; +} + +.columns.is-mobile > .column.is-two-thirds { + flex: none; + width: 66.6666%; +} + +.columns.is-mobile > .column.is-half { + flex: none; + width: 50%; +} + +.columns.is-mobile > .column.is-one-third { + flex: none; + width: 33.3333%; +} + +.columns.is-mobile > .column.is-one-quarter { + flex: none; + width: 25%; +} + +.columns.is-mobile > .column.is-one-fifth { + flex: none; + width: 20%; +} + +.columns.is-mobile > .column.is-two-fifths { + flex: none; + width: 40%; +} + +.columns.is-mobile > .column.is-three-fifths { + flex: none; + width: 60%; +} + +.columns.is-mobile > .column.is-four-fifths { + flex: none; + width: 80%; +} + +.columns.is-mobile > .column.is-offset-three-quarters { + margin-left: 75%; +} + +.columns.is-mobile > .column.is-offset-two-thirds { + margin-left: 66.6666%; +} + +.columns.is-mobile > .column.is-offset-half { + margin-left: 50%; +} + +.columns.is-mobile > .column.is-offset-one-third { + margin-left: 33.3333%; +} + +.columns.is-mobile > .column.is-offset-one-quarter { + margin-left: 25%; +} + +.columns.is-mobile > .column.is-offset-one-fifth { + margin-left: 20%; +} + +.columns.is-mobile > .column.is-offset-two-fifths { + margin-left: 40%; +} + +.columns.is-mobile > .column.is-offset-three-fifths { + margin-left: 60%; +} + +.columns.is-mobile > .column.is-offset-four-fifths { + margin-left: 80%; +} + +.columns.is-mobile > .column.is-0 { + flex: none; + width: 0%; +} + +.columns.is-mobile > .column.is-offset-0 { + margin-left: 0%; +} + +.columns.is-mobile > .column.is-1 { + flex: none; + width: 8.33333%; +} + +.columns.is-mobile > .column.is-offset-1 { + margin-left: 8.33333%; +} + +.columns.is-mobile > .column.is-2 { + flex: none; + width: 16.66667%; +} + +.columns.is-mobile > .column.is-offset-2 { + margin-left: 16.66667%; +} + +.columns.is-mobile > .column.is-3 { + flex: none; + width: 25%; +} + +.columns.is-mobile > .column.is-offset-3 { + margin-left: 25%; +} + +.columns.is-mobile > .column.is-4 { + flex: none; + width: 33.33333%; +} + +.columns.is-mobile > .column.is-offset-4 { + margin-left: 33.33333%; +} + +.columns.is-mobile > .column.is-5 { + flex: none; + width: 41.66667%; +} + +.columns.is-mobile > .column.is-offset-5 { + margin-left: 41.66667%; +} + +.columns.is-mobile > .column.is-6 { + flex: none; + width: 50%; +} + +.columns.is-mobile > .column.is-offset-6 { + margin-left: 50%; +} + +.columns.is-mobile > .column.is-7 { + flex: none; + width: 58.33333%; +} + +.columns.is-mobile > .column.is-offset-7 { + margin-left: 58.33333%; +} + +.columns.is-mobile > .column.is-8 { + flex: none; + width: 66.66667%; +} + +.columns.is-mobile > .column.is-offset-8 { + margin-left: 66.66667%; +} + +.columns.is-mobile > .column.is-9 { + flex: none; + width: 75%; +} + +.columns.is-mobile > .column.is-offset-9 { + margin-left: 75%; +} + +.columns.is-mobile > .column.is-10 { + flex: none; + width: 83.33333%; +} + +.columns.is-mobile > .column.is-offset-10 { + margin-left: 83.33333%; +} + +.columns.is-mobile > .column.is-11 { + flex: none; + width: 91.66667%; +} + +.columns.is-mobile > .column.is-offset-11 { + margin-left: 91.66667%; +} + +.columns.is-mobile > .column.is-12 { + flex: none; + width: 100%; +} + +.columns.is-mobile > .column.is-offset-12 { + margin-left: 100%; +} + +@media screen and (max-width: 768px) { + .column.is-narrow-mobile { + flex: none; + } + .column.is-full-mobile { + flex: none; + width: 100%; + } + .column.is-three-quarters-mobile { + flex: none; + width: 75%; + } + .column.is-two-thirds-mobile { + flex: none; + width: 66.6666%; + } + .column.is-half-mobile { + flex: none; + width: 50%; + } + .column.is-one-third-mobile { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-mobile { + flex: none; + width: 25%; + } + .column.is-one-fifth-mobile { + flex: none; + width: 20%; + } + .column.is-two-fifths-mobile { + flex: none; + width: 40%; + } + .column.is-three-fifths-mobile { + flex: none; + width: 60%; + } + .column.is-four-fifths-mobile { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-mobile { + margin-left: 75%; + } + .column.is-offset-two-thirds-mobile { + margin-left: 66.6666%; + } + .column.is-offset-half-mobile { + margin-left: 50%; + } + .column.is-offset-one-third-mobile { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-mobile { + margin-left: 25%; + } + .column.is-offset-one-fifth-mobile { + margin-left: 20%; + } + .column.is-offset-two-fifths-mobile { + margin-left: 40%; + } + .column.is-offset-three-fifths-mobile { + margin-left: 60%; + } + .column.is-offset-four-fifths-mobile { + margin-left: 80%; + } + .column.is-0-mobile { + flex: none; + width: 0%; + } + .column.is-offset-0-mobile { + margin-left: 0%; + } + .column.is-1-mobile { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-mobile { + margin-left: 8.33333%; + } + .column.is-2-mobile { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-mobile { + margin-left: 16.66667%; + } + .column.is-3-mobile { + flex: none; + width: 25%; + } + .column.is-offset-3-mobile { + margin-left: 25%; + } + .column.is-4-mobile { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-mobile { + margin-left: 33.33333%; + } + .column.is-5-mobile { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-mobile { + margin-left: 41.66667%; + } + .column.is-6-mobile { + flex: none; + width: 50%; + } + .column.is-offset-6-mobile { + margin-left: 50%; + } + .column.is-7-mobile { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-mobile { + margin-left: 58.33333%; + } + .column.is-8-mobile { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-mobile { + margin-left: 66.66667%; + } + .column.is-9-mobile { + flex: none; + width: 75%; + } + .column.is-offset-9-mobile { + margin-left: 75%; + } + .column.is-10-mobile { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-mobile { + margin-left: 83.33333%; + } + .column.is-11-mobile { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-mobile { + margin-left: 91.66667%; + } + .column.is-12-mobile { + flex: none; + width: 100%; + } + .column.is-offset-12-mobile { + margin-left: 100%; + } +} + +@media screen and (min-width: 769px), print { + .column.is-narrow, .column.is-narrow-tablet { + flex: none; + } + .column.is-full, .column.is-full-tablet { + flex: none; + width: 100%; + } + .column.is-three-quarters, .column.is-three-quarters-tablet { + flex: none; + width: 75%; + } + .column.is-two-thirds, .column.is-two-thirds-tablet { + flex: none; + width: 66.6666%; + } + .column.is-half, .column.is-half-tablet { + flex: none; + width: 50%; + } + .column.is-one-third, .column.is-one-third-tablet { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter, .column.is-one-quarter-tablet { + flex: none; + width: 25%; + } + .column.is-one-fifth, .column.is-one-fifth-tablet { + flex: none; + width: 20%; + } + .column.is-two-fifths, .column.is-two-fifths-tablet { + flex: none; + width: 40%; + } + .column.is-three-fifths, .column.is-three-fifths-tablet { + flex: none; + width: 60%; + } + .column.is-four-fifths, .column.is-four-fifths-tablet { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters, .column.is-offset-three-quarters-tablet { + margin-left: 75%; + } + .column.is-offset-two-thirds, .column.is-offset-two-thirds-tablet { + margin-left: 66.6666%; + } + .column.is-offset-half, .column.is-offset-half-tablet { + margin-left: 50%; + } + .column.is-offset-one-third, .column.is-offset-one-third-tablet { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter, .column.is-offset-one-quarter-tablet { + margin-left: 25%; + } + .column.is-offset-one-fifth, .column.is-offset-one-fifth-tablet { + margin-left: 20%; + } + .column.is-offset-two-fifths, .column.is-offset-two-fifths-tablet { + margin-left: 40%; + } + .column.is-offset-three-fifths, .column.is-offset-three-fifths-tablet { + margin-left: 60%; + } + .column.is-offset-four-fifths, .column.is-offset-four-fifths-tablet { + margin-left: 80%; + } + .column.is-0, .column.is-0-tablet { + flex: none; + width: 0%; + } + .column.is-offset-0, .column.is-offset-0-tablet { + margin-left: 0%; + } + .column.is-1, .column.is-1-tablet { + flex: none; + width: 8.33333%; + } + .column.is-offset-1, .column.is-offset-1-tablet { + margin-left: 8.33333%; + } + .column.is-2, .column.is-2-tablet { + flex: none; + width: 16.66667%; + } + .column.is-offset-2, .column.is-offset-2-tablet { + margin-left: 16.66667%; + } + .column.is-3, .column.is-3-tablet { + flex: none; + width: 25%; + } + .column.is-offset-3, .column.is-offset-3-tablet { + margin-left: 25%; + } + .column.is-4, .column.is-4-tablet { + flex: none; + width: 33.33333%; + } + .column.is-offset-4, .column.is-offset-4-tablet { + margin-left: 33.33333%; + } + .column.is-5, .column.is-5-tablet { + flex: none; + width: 41.66667%; + } + .column.is-offset-5, .column.is-offset-5-tablet { + margin-left: 41.66667%; + } + .column.is-6, .column.is-6-tablet { + flex: none; + width: 50%; + } + .column.is-offset-6, .column.is-offset-6-tablet { + margin-left: 50%; + } + .column.is-7, .column.is-7-tablet { + flex: none; + width: 58.33333%; + } + .column.is-offset-7, .column.is-offset-7-tablet { + margin-left: 58.33333%; + } + .column.is-8, .column.is-8-tablet { + flex: none; + width: 66.66667%; + } + .column.is-offset-8, .column.is-offset-8-tablet { + margin-left: 66.66667%; + } + .column.is-9, .column.is-9-tablet { + flex: none; + width: 75%; + } + .column.is-offset-9, .column.is-offset-9-tablet { + margin-left: 75%; + } + .column.is-10, .column.is-10-tablet { + flex: none; + width: 83.33333%; + } + .column.is-offset-10, .column.is-offset-10-tablet { + margin-left: 83.33333%; + } + .column.is-11, .column.is-11-tablet { + flex: none; + width: 91.66667%; + } + .column.is-offset-11, .column.is-offset-11-tablet { + margin-left: 91.66667%; + } + .column.is-12, .column.is-12-tablet { + flex: none; + width: 100%; + } + .column.is-offset-12, .column.is-offset-12-tablet { + margin-left: 100%; + } +} + +@media screen and (max-width: 1023px) { + .column.is-narrow-touch { + flex: none; + } + .column.is-full-touch { + flex: none; + width: 100%; + } + .column.is-three-quarters-touch { + flex: none; + width: 75%; + } + .column.is-two-thirds-touch { + flex: none; + width: 66.6666%; + } + .column.is-half-touch { + flex: none; + width: 50%; + } + .column.is-one-third-touch { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-touch { + flex: none; + width: 25%; + } + .column.is-one-fifth-touch { + flex: none; + width: 20%; + } + .column.is-two-fifths-touch { + flex: none; + width: 40%; + } + .column.is-three-fifths-touch { + flex: none; + width: 60%; + } + .column.is-four-fifths-touch { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-touch { + margin-left: 75%; + } + .column.is-offset-two-thirds-touch { + margin-left: 66.6666%; + } + .column.is-offset-half-touch { + margin-left: 50%; + } + .column.is-offset-one-third-touch { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-touch { + margin-left: 25%; + } + .column.is-offset-one-fifth-touch { + margin-left: 20%; + } + .column.is-offset-two-fifths-touch { + margin-left: 40%; + } + .column.is-offset-three-fifths-touch { + margin-left: 60%; + } + .column.is-offset-four-fifths-touch { + margin-left: 80%; + } + .column.is-0-touch { + flex: none; + width: 0%; + } + .column.is-offset-0-touch { + margin-left: 0%; + } + .column.is-1-touch { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-touch { + margin-left: 8.33333%; + } + .column.is-2-touch { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-touch { + margin-left: 16.66667%; + } + .column.is-3-touch { + flex: none; + width: 25%; + } + .column.is-offset-3-touch { + margin-left: 25%; + } + .column.is-4-touch { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-touch { + margin-left: 33.33333%; + } + .column.is-5-touch { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-touch { + margin-left: 41.66667%; + } + .column.is-6-touch { + flex: none; + width: 50%; + } + .column.is-offset-6-touch { + margin-left: 50%; + } + .column.is-7-touch { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-touch { + margin-left: 58.33333%; + } + .column.is-8-touch { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-touch { + margin-left: 66.66667%; + } + .column.is-9-touch { + flex: none; + width: 75%; + } + .column.is-offset-9-touch { + margin-left: 75%; + } + .column.is-10-touch { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-touch { + margin-left: 83.33333%; + } + .column.is-11-touch { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-touch { + margin-left: 91.66667%; + } + .column.is-12-touch { + flex: none; + width: 100%; + } + .column.is-offset-12-touch { + margin-left: 100%; + } +} + +@media screen and (min-width: 1024px) { + .column.is-narrow-desktop { + flex: none; + } + .column.is-full-desktop { + flex: none; + width: 100%; + } + .column.is-three-quarters-desktop { + flex: none; + width: 75%; + } + .column.is-two-thirds-desktop { + flex: none; + width: 66.6666%; + } + .column.is-half-desktop { + flex: none; + width: 50%; + } + .column.is-one-third-desktop { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-desktop { + flex: none; + width: 25%; + } + .column.is-one-fifth-desktop { + flex: none; + width: 20%; + } + .column.is-two-fifths-desktop { + flex: none; + width: 40%; + } + .column.is-three-fifths-desktop { + flex: none; + width: 60%; + } + .column.is-four-fifths-desktop { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-desktop { + margin-left: 75%; + } + .column.is-offset-two-thirds-desktop { + margin-left: 66.6666%; + } + .column.is-offset-half-desktop { + margin-left: 50%; + } + .column.is-offset-one-third-desktop { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-desktop { + margin-left: 25%; + } + .column.is-offset-one-fifth-desktop { + margin-left: 20%; + } + .column.is-offset-two-fifths-desktop { + margin-left: 40%; + } + .column.is-offset-three-fifths-desktop { + margin-left: 60%; + } + .column.is-offset-four-fifths-desktop { + margin-left: 80%; + } + .column.is-0-desktop { + flex: none; + width: 0%; + } + .column.is-offset-0-desktop { + margin-left: 0%; + } + .column.is-1-desktop { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-desktop { + margin-left: 8.33333%; + } + .column.is-2-desktop { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-desktop { + margin-left: 16.66667%; + } + .column.is-3-desktop { + flex: none; + width: 25%; + } + .column.is-offset-3-desktop { + margin-left: 25%; + } + .column.is-4-desktop { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-desktop { + margin-left: 33.33333%; + } + .column.is-5-desktop { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-desktop { + margin-left: 41.66667%; + } + .column.is-6-desktop { + flex: none; + width: 50%; + } + .column.is-offset-6-desktop { + margin-left: 50%; + } + .column.is-7-desktop { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-desktop { + margin-left: 58.33333%; + } + .column.is-8-desktop { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-desktop { + margin-left: 66.66667%; + } + .column.is-9-desktop { + flex: none; + width: 75%; + } + .column.is-offset-9-desktop { + margin-left: 75%; + } + .column.is-10-desktop { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-desktop { + margin-left: 83.33333%; + } + .column.is-11-desktop { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-desktop { + margin-left: 91.66667%; + } + .column.is-12-desktop { + flex: none; + width: 100%; + } + .column.is-offset-12-desktop { + margin-left: 100%; + } +} + +@media screen and (min-width: 1216px) { + .column.is-narrow-widescreen { + flex: none; + } + .column.is-full-widescreen { + flex: none; + width: 100%; + } + .column.is-three-quarters-widescreen { + flex: none; + width: 75%; + } + .column.is-two-thirds-widescreen { + flex: none; + width: 66.6666%; + } + .column.is-half-widescreen { + flex: none; + width: 50%; + } + .column.is-one-third-widescreen { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-widescreen { + flex: none; + width: 25%; + } + .column.is-one-fifth-widescreen { + flex: none; + width: 20%; + } + .column.is-two-fifths-widescreen { + flex: none; + width: 40%; + } + .column.is-three-fifths-widescreen { + flex: none; + width: 60%; + } + .column.is-four-fifths-widescreen { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-widescreen { + margin-left: 75%; + } + .column.is-offset-two-thirds-widescreen { + margin-left: 66.6666%; + } + .column.is-offset-half-widescreen { + margin-left: 50%; + } + .column.is-offset-one-third-widescreen { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-widescreen { + margin-left: 25%; + } + .column.is-offset-one-fifth-widescreen { + margin-left: 20%; + } + .column.is-offset-two-fifths-widescreen { + margin-left: 40%; + } + .column.is-offset-three-fifths-widescreen { + margin-left: 60%; + } + .column.is-offset-four-fifths-widescreen { + margin-left: 80%; + } + .column.is-0-widescreen { + flex: none; + width: 0%; + } + .column.is-offset-0-widescreen { + margin-left: 0%; + } + .column.is-1-widescreen { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-widescreen { + margin-left: 8.33333%; + } + .column.is-2-widescreen { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-widescreen { + margin-left: 16.66667%; + } + .column.is-3-widescreen { + flex: none; + width: 25%; + } + .column.is-offset-3-widescreen { + margin-left: 25%; + } + .column.is-4-widescreen { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-widescreen { + margin-left: 33.33333%; + } + .column.is-5-widescreen { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-widescreen { + margin-left: 41.66667%; + } + .column.is-6-widescreen { + flex: none; + width: 50%; + } + .column.is-offset-6-widescreen { + margin-left: 50%; + } + .column.is-7-widescreen { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-widescreen { + margin-left: 58.33333%; + } + .column.is-8-widescreen { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-widescreen { + margin-left: 66.66667%; + } + .column.is-9-widescreen { + flex: none; + width: 75%; + } + .column.is-offset-9-widescreen { + margin-left: 75%; + } + .column.is-10-widescreen { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-widescreen { + margin-left: 83.33333%; + } + .column.is-11-widescreen { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-widescreen { + margin-left: 91.66667%; + } + .column.is-12-widescreen { + flex: none; + width: 100%; + } + .column.is-offset-12-widescreen { + margin-left: 100%; + } +} + +@media screen and (min-width: 1408px) { + .column.is-narrow-fullhd { + flex: none; + } + .column.is-full-fullhd { + flex: none; + width: 100%; + } + .column.is-three-quarters-fullhd { + flex: none; + width: 75%; + } + .column.is-two-thirds-fullhd { + flex: none; + width: 66.6666%; + } + .column.is-half-fullhd { + flex: none; + width: 50%; + } + .column.is-one-third-fullhd { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-fullhd { + flex: none; + width: 25%; + } + .column.is-one-fifth-fullhd { + flex: none; + width: 20%; + } + .column.is-two-fifths-fullhd { + flex: none; + width: 40%; + } + .column.is-three-fifths-fullhd { + flex: none; + width: 60%; + } + .column.is-four-fifths-fullhd { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-fullhd { + margin-left: 75%; + } + .column.is-offset-two-thirds-fullhd { + margin-left: 66.6666%; + } + .column.is-offset-half-fullhd { + margin-left: 50%; + } + .column.is-offset-one-third-fullhd { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-fullhd { + margin-left: 25%; + } + .column.is-offset-one-fifth-fullhd { + margin-left: 20%; + } + .column.is-offset-two-fifths-fullhd { + margin-left: 40%; + } + .column.is-offset-three-fifths-fullhd { + margin-left: 60%; + } + .column.is-offset-four-fifths-fullhd { + margin-left: 80%; + } + .column.is-0-fullhd { + flex: none; + width: 0%; + } + .column.is-offset-0-fullhd { + margin-left: 0%; + } + .column.is-1-fullhd { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-fullhd { + margin-left: 8.33333%; + } + .column.is-2-fullhd { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-fullhd { + margin-left: 16.66667%; + } + .column.is-3-fullhd { + flex: none; + width: 25%; + } + .column.is-offset-3-fullhd { + margin-left: 25%; + } + .column.is-4-fullhd { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-fullhd { + margin-left: 33.33333%; + } + .column.is-5-fullhd { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-fullhd { + margin-left: 41.66667%; + } + .column.is-6-fullhd { + flex: none; + width: 50%; + } + .column.is-offset-6-fullhd { + margin-left: 50%; + } + .column.is-7-fullhd { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-fullhd { + margin-left: 58.33333%; + } + .column.is-8-fullhd { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-fullhd { + margin-left: 66.66667%; + } + .column.is-9-fullhd { + flex: none; + width: 75%; + } + .column.is-offset-9-fullhd { + margin-left: 75%; + } + .column.is-10-fullhd { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-fullhd { + margin-left: 83.33333%; + } + .column.is-11-fullhd { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-fullhd { + margin-left: 91.66667%; + } + .column.is-12-fullhd { + flex: none; + width: 100%; + } + .column.is-offset-12-fullhd { + margin-left: 100%; + } +} + +.columns { + margin-left: -0.75rem; + margin-right: -0.75rem; + margin-top: -0.75rem; +} + +.columns:last-child { + margin-bottom: -0.75rem; +} + +.columns:not(:last-child) { + margin-bottom: calc(1.5rem - 0.75rem); +} + +.columns.is-centered { + justify-content: center; +} + +.columns.is-gapless { + margin-left: 0; + margin-right: 0; + margin-top: 0; +} + +.columns.is-gapless > .column { + margin: 0; + padding: 0 !important; +} + +.columns.is-gapless:not(:last-child) { + margin-bottom: 1.5rem; +} + +.columns.is-gapless:last-child { + margin-bottom: 0; +} + +.columns.is-mobile { + display: flex; +} + +.columns.is-multiline { + flex-wrap: wrap; +} + +.columns.is-vcentered { + align-items: center; +} + +@media screen and (min-width: 769px), print { + .columns:not(.is-desktop) { + display: flex; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-desktop { + display: flex; + } +} + +.columns.is-variable { + --columnGap: 0.75rem; + margin-left: calc(-1 * var(--columnGap)); + margin-right: calc(-1 * var(--columnGap)); +} + +.columns.is-variable .column { + padding-left: var(--columnGap); + padding-right: var(--columnGap); +} + +.columns.is-variable.is-0 { + --columnGap: 0rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-0-mobile { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-0-tablet { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-0-tablet-only { + --columnGap: 0rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-0-touch { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-0-desktop { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-0-desktop-only { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-0-widescreen { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-0-widescreen-only { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-0-fullhd { + --columnGap: 0rem; + } +} + +.columns.is-variable.is-1 { + --columnGap: 0.25rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-1-mobile { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-1-tablet { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-1-tablet-only { + --columnGap: 0.25rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-1-touch { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-1-desktop { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-1-desktop-only { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-1-widescreen { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-1-widescreen-only { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-1-fullhd { + --columnGap: 0.25rem; + } +} + +.columns.is-variable.is-2 { + --columnGap: 0.5rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-2-mobile { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-2-tablet { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-2-tablet-only { + --columnGap: 0.5rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-2-touch { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-2-desktop { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-2-desktop-only { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-2-widescreen { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-2-widescreen-only { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-2-fullhd { + --columnGap: 0.5rem; + } +} + +.columns.is-variable.is-3 { + --columnGap: 0.75rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-3-mobile { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-3-tablet { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-3-tablet-only { + --columnGap: 0.75rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-3-touch { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-3-desktop { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-3-desktop-only { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-3-widescreen { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-3-widescreen-only { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-3-fullhd { + --columnGap: 0.75rem; + } +} + +.columns.is-variable.is-4 { + --columnGap: 1rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-4-mobile { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-4-tablet { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-4-tablet-only { + --columnGap: 1rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-4-touch { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-4-desktop { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-4-desktop-only { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-4-widescreen { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-4-widescreen-only { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-4-fullhd { + --columnGap: 1rem; + } +} + +.columns.is-variable.is-5 { + --columnGap: 1.25rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-5-mobile { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-5-tablet { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-5-tablet-only { + --columnGap: 1.25rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-5-touch { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-5-desktop { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-5-desktop-only { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-5-widescreen { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-5-widescreen-only { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-5-fullhd { + --columnGap: 1.25rem; + } +} + +.columns.is-variable.is-6 { + --columnGap: 1.5rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-6-mobile { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-6-tablet { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-6-tablet-only { + --columnGap: 1.5rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-6-touch { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-6-desktop { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-6-desktop-only { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-6-widescreen { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-6-widescreen-only { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-6-fullhd { + --columnGap: 1.5rem; + } +} + +.columns.is-variable.is-7 { + --columnGap: 1.75rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-7-mobile { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-7-tablet { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-7-tablet-only { + --columnGap: 1.75rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-7-touch { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-7-desktop { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-7-desktop-only { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-7-widescreen { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-7-widescreen-only { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-7-fullhd { + --columnGap: 1.75rem; + } +} + +.columns.is-variable.is-8 { + --columnGap: 2rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-8-mobile { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-8-tablet { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-8-tablet-only { + --columnGap: 2rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-8-touch { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-8-desktop { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-8-desktop-only { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-8-widescreen { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-8-widescreen-only { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-8-fullhd { + --columnGap: 2rem; + } +} + +.tile { + align-items: stretch; + display: block; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 1; + min-height: -webkit-min-content; + min-height: -moz-min-content; + min-height: min-content; +} + +.tile.is-ancestor { + margin-left: -0.75rem; + margin-right: -0.75rem; + margin-top: -0.75rem; +} + +.tile.is-ancestor:last-child { + margin-bottom: -0.75rem; +} + +.tile.is-ancestor:not(:last-child) { + margin-bottom: 0.75rem; +} + +.tile.is-child { + margin: 0 !important; +} + +.tile.is-parent { + padding: 0.75rem; +} + +.tile.is-vertical { + flex-direction: column; +} + +.tile.is-vertical > .tile.is-child:not(:last-child) { + margin-bottom: 1.5rem !important; +} + +@media screen and (min-width: 769px), print { + .tile:not(.is-child) { + display: flex; + } + .tile.is-1 { + flex: none; + width: 8.33333%; + } + .tile.is-2 { + flex: none; + width: 16.66667%; + } + .tile.is-3 { + flex: none; + width: 25%; + } + .tile.is-4 { + flex: none; + width: 33.33333%; + } + .tile.is-5 { + flex: none; + width: 41.66667%; + } + .tile.is-6 { + flex: none; + width: 50%; + } + .tile.is-7 { + flex: none; + width: 58.33333%; + } + .tile.is-8 { + flex: none; + width: 66.66667%; + } + .tile.is-9 { + flex: none; + width: 75%; + } + .tile.is-10 { + flex: none; + width: 83.33333%; + } + .tile.is-11 { + flex: none; + width: 91.66667%; + } + .tile.is-12 { + flex: none; + width: 100%; + } +} + +.hero { + align-items: stretch; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.hero .navbar { + background: none; +} + +.hero .tabs ul { + border-bottom: none; +} + +.hero.is-white { + background-color: white; + color: #0a0a0a; +} + +.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-white strong { + color: inherit; +} + +.hero.is-white .title { + color: #0a0a0a; +} + +.hero.is-white .subtitle { + color: rgba(10, 10, 10, 0.9); +} + +.hero.is-white .subtitle a:not(.button), +.hero.is-white .subtitle strong { + color: #0a0a0a; +} + +@media screen and (max-width: 1023px) { + .hero.is-white .navbar-menu { + background-color: white; + } +} + +.hero.is-white .navbar-item, +.hero.is-white .navbar-link { + color: rgba(10, 10, 10, 0.7); +} + +.hero.is-white a.navbar-item:hover, .hero.is-white a.navbar-item.is-active, +.hero.is-white .navbar-link:hover, +.hero.is-white .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; +} + +.hero.is-white .tabs a { + color: #0a0a0a; + opacity: 0.9; +} + +.hero.is-white .tabs a:hover { + opacity: 1; +} + +.hero.is-white .tabs li.is-active a { + opacity: 1; +} + +.hero.is-white .tabs.is-boxed a, .hero.is-white .tabs.is-toggle a { + color: #0a0a0a; +} + +.hero.is-white .tabs.is-boxed a:hover, .hero.is-white .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-white .tabs.is-boxed li.is-active a, .hero.is-white .tabs.is-boxed li.is-active a:hover, .hero.is-white .tabs.is-toggle li.is-active a, .hero.is-white .tabs.is-toggle li.is-active a:hover { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.hero.is-white.is-bold { + background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-white.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); + } +} + +.hero.is-black { + background-color: #0a0a0a; + color: white; +} + +.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-black strong { + color: inherit; +} + +.hero.is-black .title { + color: white; +} + +.hero.is-black .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-black .subtitle a:not(.button), +.hero.is-black .subtitle strong { + color: white; +} + +@media screen and (max-width: 1023px) { + .hero.is-black .navbar-menu { + background-color: #0a0a0a; + } +} + +.hero.is-black .navbar-item, +.hero.is-black .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-black a.navbar-item:hover, .hero.is-black a.navbar-item.is-active, +.hero.is-black .navbar-link:hover, +.hero.is-black .navbar-link.is-active { + background-color: black; + color: white; +} + +.hero.is-black .tabs a { + color: white; + opacity: 0.9; +} + +.hero.is-black .tabs a:hover { + opacity: 1; +} + +.hero.is-black .tabs li.is-active a { + opacity: 1; +} + +.hero.is-black .tabs.is-boxed a, .hero.is-black .tabs.is-toggle a { + color: white; +} + +.hero.is-black .tabs.is-boxed a:hover, .hero.is-black .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-black .tabs.is-boxed li.is-active a, .hero.is-black .tabs.is-boxed li.is-active a:hover, .hero.is-black .tabs.is-toggle li.is-active a, .hero.is-black .tabs.is-toggle li.is-active a:hover { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.hero.is-black.is-bold { + background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-black.is-bold .navbar-menu { + background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); + } +} + +.hero.is-light { + background-color: whitesmoke; + color: #363636; +} + +.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-light strong { + color: inherit; +} + +.hero.is-light .title { + color: #363636; +} + +.hero.is-light .subtitle { + color: rgba(54, 54, 54, 0.9); +} + +.hero.is-light .subtitle a:not(.button), +.hero.is-light .subtitle strong { + color: #363636; +} + +@media screen and (max-width: 1023px) { + .hero.is-light .navbar-menu { + background-color: whitesmoke; + } +} + +.hero.is-light .navbar-item, +.hero.is-light .navbar-link { + color: rgba(54, 54, 54, 0.7); +} + +.hero.is-light a.navbar-item:hover, .hero.is-light a.navbar-item.is-active, +.hero.is-light .navbar-link:hover, +.hero.is-light .navbar-link.is-active { + background-color: #e8e8e8; + color: #363636; +} + +.hero.is-light .tabs a { + color: #363636; + opacity: 0.9; +} + +.hero.is-light .tabs a:hover { + opacity: 1; +} + +.hero.is-light .tabs li.is-active a { + opacity: 1; +} + +.hero.is-light .tabs.is-boxed a, .hero.is-light .tabs.is-toggle a { + color: #363636; +} + +.hero.is-light .tabs.is-boxed a:hover, .hero.is-light .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-light .tabs.is-boxed li.is-active a, .hero.is-light .tabs.is-boxed li.is-active a:hover, .hero.is-light .tabs.is-toggle li.is-active a, .hero.is-light .tabs.is-toggle li.is-active a:hover { + background-color: #363636; + border-color: #363636; + color: whitesmoke; +} + +.hero.is-light.is-bold { + background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-light.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); + } +} + +.hero.is-dark { + background-color: #363636; + color: whitesmoke; +} + +.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-dark strong { + color: inherit; +} + +.hero.is-dark .title { + color: whitesmoke; +} + +.hero.is-dark .subtitle { + color: rgba(245, 245, 245, 0.9); +} + +.hero.is-dark .subtitle a:not(.button), +.hero.is-dark .subtitle strong { + color: whitesmoke; +} + +@media screen and (max-width: 1023px) { + .hero.is-dark .navbar-menu { + background-color: #363636; + } +} + +.hero.is-dark .navbar-item, +.hero.is-dark .navbar-link { + color: rgba(245, 245, 245, 0.7); +} + +.hero.is-dark a.navbar-item:hover, .hero.is-dark a.navbar-item.is-active, +.hero.is-dark .navbar-link:hover, +.hero.is-dark .navbar-link.is-active { + background-color: #292929; + color: whitesmoke; +} + +.hero.is-dark .tabs a { + color: whitesmoke; + opacity: 0.9; +} + +.hero.is-dark .tabs a:hover { + opacity: 1; +} + +.hero.is-dark .tabs li.is-active a { + opacity: 1; +} + +.hero.is-dark .tabs.is-boxed a, .hero.is-dark .tabs.is-toggle a { + color: whitesmoke; +} + +.hero.is-dark .tabs.is-boxed a:hover, .hero.is-dark .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-dark .tabs.is-boxed li.is-active a, .hero.is-dark .tabs.is-boxed li.is-active a:hover, .hero.is-dark .tabs.is-toggle li.is-active a, .hero.is-dark .tabs.is-toggle li.is-active a:hover { + background-color: whitesmoke; + border-color: whitesmoke; + color: #363636; +} + +.hero.is-dark.is-bold { + background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-dark.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%); + } +} + +.hero.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-primary strong { + color: inherit; +} + +.hero.is-primary .title { + color: #fff; +} + +.hero.is-primary .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-primary .subtitle a:not(.button), +.hero.is-primary .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-primary .navbar-menu { + background-color: #00d1b2; + } +} + +.hero.is-primary .navbar-item, +.hero.is-primary .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-primary a.navbar-item:hover, .hero.is-primary a.navbar-item.is-active, +.hero.is-primary .navbar-link:hover, +.hero.is-primary .navbar-link.is-active { + background-color: #00b89c; + color: #fff; +} + +.hero.is-primary .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-primary .tabs a:hover { + opacity: 1; +} + +.hero.is-primary .tabs li.is-active a { + opacity: 1; +} + +.hero.is-primary .tabs.is-boxed a, .hero.is-primary .tabs.is-toggle a { + color: #fff; +} + +.hero.is-primary .tabs.is-boxed a:hover, .hero.is-primary .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-primary .tabs.is-boxed li.is-active a, .hero.is-primary .tabs.is-boxed li.is-active a:hover, .hero.is-primary .tabs.is-toggle li.is-active a, .hero.is-primary .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #00d1b2; +} + +.hero.is-primary.is-bold { + background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-primary.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%); + } +} + +.hero.is-link { + background-color: #3273dc; + color: #fff; +} + +.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-link strong { + color: inherit; +} + +.hero.is-link .title { + color: #fff; +} + +.hero.is-link .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-link .subtitle a:not(.button), +.hero.is-link .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-link .navbar-menu { + background-color: #3273dc; + } +} + +.hero.is-link .navbar-item, +.hero.is-link .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-link a.navbar-item:hover, .hero.is-link a.navbar-item.is-active, +.hero.is-link .navbar-link:hover, +.hero.is-link .navbar-link.is-active { + background-color: #2366d1; + color: #fff; +} + +.hero.is-link .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-link .tabs a:hover { + opacity: 1; +} + +.hero.is-link .tabs li.is-active a { + opacity: 1; +} + +.hero.is-link .tabs.is-boxed a, .hero.is-link .tabs.is-toggle a { + color: #fff; +} + +.hero.is-link .tabs.is-boxed a:hover, .hero.is-link .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-link .tabs.is-boxed li.is-active a, .hero.is-link .tabs.is-boxed li.is-active a:hover, .hero.is-link .tabs.is-toggle li.is-active a, .hero.is-link .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #3273dc; +} + +.hero.is-link.is-bold { + background-image: linear-gradient(141deg, #1577c6 0%, #3273dc 71%, #4366e5 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-link.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #1577c6 0%, #3273dc 71%, #4366e5 100%); + } +} + +.hero.is-info { + background-color: #209cee; + color: #fff; +} + +.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-info strong { + color: inherit; +} + +.hero.is-info .title { + color: #fff; +} + +.hero.is-info .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-info .subtitle a:not(.button), +.hero.is-info .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-info .navbar-menu { + background-color: #209cee; + } +} + +.hero.is-info .navbar-item, +.hero.is-info .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-info a.navbar-item:hover, .hero.is-info a.navbar-item.is-active, +.hero.is-info .navbar-link:hover, +.hero.is-info .navbar-link.is-active { + background-color: #118fe4; + color: #fff; +} + +.hero.is-info .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-info .tabs a:hover { + opacity: 1; +} + +.hero.is-info .tabs li.is-active a { + opacity: 1; +} + +.hero.is-info .tabs.is-boxed a, .hero.is-info .tabs.is-toggle a { + color: #fff; +} + +.hero.is-info .tabs.is-boxed a:hover, .hero.is-info .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-info .tabs.is-boxed li.is-active a, .hero.is-info .tabs.is-boxed li.is-active a:hover, .hero.is-info .tabs.is-toggle li.is-active a, .hero.is-info .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #209cee; +} + +.hero.is-info.is-bold { + background-image: linear-gradient(141deg, #04a6d7 0%, #209cee 71%, #3287f5 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-info.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #04a6d7 0%, #209cee 71%, #3287f5 100%); + } +} + +.hero.is-success { + background-color: #23d160; + color: #fff; +} + +.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-success strong { + color: inherit; +} + +.hero.is-success .title { + color: #fff; +} + +.hero.is-success .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-success .subtitle a:not(.button), +.hero.is-success .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-success .navbar-menu { + background-color: #23d160; + } +} + +.hero.is-success .navbar-item, +.hero.is-success .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-success a.navbar-item:hover, .hero.is-success a.navbar-item.is-active, +.hero.is-success .navbar-link:hover, +.hero.is-success .navbar-link.is-active { + background-color: #20bc56; + color: #fff; +} + +.hero.is-success .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-success .tabs a:hover { + opacity: 1; +} + +.hero.is-success .tabs li.is-active a { + opacity: 1; +} + +.hero.is-success .tabs.is-boxed a, .hero.is-success .tabs.is-toggle a { + color: #fff; +} + +.hero.is-success .tabs.is-boxed a:hover, .hero.is-success .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-success .tabs.is-boxed li.is-active a, .hero.is-success .tabs.is-boxed li.is-active a:hover, .hero.is-success .tabs.is-toggle li.is-active a, .hero.is-success .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #23d160; +} + +.hero.is-success.is-bold { + background-image: linear-gradient(141deg, #12af2f 0%, #23d160 71%, #2ce28a 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-success.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #12af2f 0%, #23d160 71%, #2ce28a 100%); + } +} + +.hero.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-warning strong { + color: inherit; +} + +.hero.is-warning .title { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .subtitle { + color: rgba(0, 0, 0, 0.9); +} + +.hero.is-warning .subtitle a:not(.button), +.hero.is-warning .subtitle strong { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (max-width: 1023px) { + .hero.is-warning .navbar-menu { + background-color: #ffdd57; + } +} + +.hero.is-warning .navbar-item, +.hero.is-warning .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning a.navbar-item:hover, .hero.is-warning a.navbar-item.is-active, +.hero.is-warning .navbar-link:hover, +.hero.is-warning .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .tabs a { + color: rgba(0, 0, 0, 0.7); + opacity: 0.9; +} + +.hero.is-warning .tabs a:hover { + opacity: 1; +} + +.hero.is-warning .tabs li.is-active a { + opacity: 1; +} + +.hero.is-warning .tabs.is-boxed a, .hero.is-warning .tabs.is-toggle a { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .tabs.is-boxed a:hover, .hero.is-warning .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-warning .tabs.is-boxed li.is-active a, .hero.is-warning .tabs.is-boxed li.is-active a:hover, .hero.is-warning .tabs.is-toggle li.is-active a, .hero.is-warning .tabs.is-toggle li.is-active a:hover { + background-color: rgba(0, 0, 0, 0.7); + border-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.hero.is-warning.is-bold { + background-image: linear-gradient(141deg, #ffaf24 0%, #ffdd57 71%, #fffa70 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-warning.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #ffaf24 0%, #ffdd57 71%, #fffa70 100%); + } +} + +.hero.is-danger { + background-color: #ff3860; + color: #fff; +} + +.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-danger strong { + color: inherit; +} + +.hero.is-danger .title { + color: #fff; +} + +.hero.is-danger .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-danger .subtitle a:not(.button), +.hero.is-danger .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-danger .navbar-menu { + background-color: #ff3860; + } +} + +.hero.is-danger .navbar-item, +.hero.is-danger .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-danger a.navbar-item:hover, .hero.is-danger a.navbar-item.is-active, +.hero.is-danger .navbar-link:hover, +.hero.is-danger .navbar-link.is-active { + background-color: #ff1f4b; + color: #fff; +} + +.hero.is-danger .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-danger .tabs a:hover { + opacity: 1; +} + +.hero.is-danger .tabs li.is-active a { + opacity: 1; +} + +.hero.is-danger .tabs.is-boxed a, .hero.is-danger .tabs.is-toggle a { + color: #fff; +} + +.hero.is-danger .tabs.is-boxed a:hover, .hero.is-danger .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-danger .tabs.is-boxed li.is-active a, .hero.is-danger .tabs.is-boxed li.is-active a:hover, .hero.is-danger .tabs.is-toggle li.is-active a, .hero.is-danger .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #ff3860; +} + +.hero.is-danger.is-bold { + background-image: linear-gradient(141deg, #ff0561 0%, #ff3860 71%, #ff5257 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-danger.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #ff0561 0%, #ff3860 71%, #ff5257 100%); + } +} + +.hero.is-small .hero-body { + padding-bottom: 1.5rem; + padding-top: 1.5rem; +} + +@media screen and (min-width: 769px), print { + .hero.is-medium .hero-body { + padding-bottom: 9rem; + padding-top: 9rem; + } +} + +@media screen and (min-width: 769px), print { + .hero.is-large .hero-body { + padding-bottom: 18rem; + padding-top: 18rem; + } +} + +.hero.is-halfheight .hero-body, .hero.is-fullheight .hero-body, .hero.is-fullheight-with-navbar .hero-body { + align-items: center; + display: flex; +} + +.hero.is-halfheight .hero-body > .container, .hero.is-fullheight .hero-body > .container, .hero.is-fullheight-with-navbar .hero-body > .container { + flex-grow: 1; + flex-shrink: 1; +} + +.hero.is-halfheight { + min-height: 50vh; +} + +.hero.is-fullheight { + min-height: 100vh; +} + +.hero-video { + overflow: hidden; +} + +.hero-video video { + left: 50%; + min-height: 100%; + min-width: 100%; + position: absolute; + top: 50%; + -webkit-transform: translate3d(-50%, -50%, 0); + transform: translate3d(-50%, -50%, 0); +} + +.hero-video.is-transparent { + opacity: 0.3; +} + +@media screen and (max-width: 768px) { + .hero-video { + display: none; + } +} + +.hero-buttons { + margin-top: 1.5rem; +} + +@media screen and (max-width: 768px) { + .hero-buttons .button { + display: flex; + } + .hero-buttons .button:not(:last-child) { + margin-bottom: 0.75rem; + } +} + +@media screen and (min-width: 769px), print { + .hero-buttons { + display: flex; + justify-content: center; + } + .hero-buttons .button:not(:last-child) { + margin-right: 1.5rem; + } +} + +.hero-head, +.hero-foot { + flex-grow: 0; + flex-shrink: 0; +} + +.hero-body { + flex-grow: 1; + flex-shrink: 0; + padding: 3rem 1.5rem; +} + +.section { + padding: 3rem 1.5rem; +} + +@media screen and (min-width: 1024px) { + .section.is-medium { + padding: 9rem 1.5rem; + } + .section.is-large { + padding: 18rem 1.5rem; + } +} + +.footer { + background-color: #fafafa; + padding: 3rem 1.5rem 6rem; +} +/*# sourceMappingURL=bulma.css.map */ \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css.map b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css.map new file mode 100644 index 00000000000..33bb0c7776c --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../bulma.sass","../sass/utilities/animations.sass","bulma.css","../sass/utilities/mixins.sass","../sass/utilities/initial-variables.sass","../sass/utilities/controls.sass","../sass/base/minireset.sass","../sass/base/generic.sass","../sass/base/helpers.sass","../sass/elements/box.sass","../sass/elements/button.sass","../sass/utilities/functions.sass","../sass/elements/container.sass","../sass/elements/content.sass","../sass/elements/icon.sass","../sass/elements/image.sass","../sass/elements/notification.sass","../sass/elements/progress.sass","../sass/elements/table.sass","../sass/elements/tag.sass","../sass/elements/title.sass","../sass/elements/other.sass","../sass/form/shared.sass","../sass/form/input-textarea.sass","../sass/form/checkbox-radio.sass","../sass/form/select.sass","../sass/form/file.sass","../sass/form/tools.sass","../sass/components/breadcrumb.sass","../sass/components/card.sass","../sass/components/dropdown.sass","../sass/components/level.sass","../sass/components/list.sass","../sass/components/media.sass","../sass/components/menu.sass","../sass/components/message.sass","../sass/components/modal.sass","../sass/components/navbar.sass","../sass/components/pagination.sass","../sass/components/panel.sass","../sass/components/tabs.sass","../sass/grid/columns.sass","../sass/grid/tiles.sass","../sass/layout/hero.sass","../sass/layout/section.sass","../sass/layout/footer.sass"],"names":[],"mappings":"AACA,6DAAA;ACDA;EACE;IACE,+BAAuB;YAAvB,uBAAuB;ECEzB;EDDA;IACE,iCAAyB;YAAzB,yBAAyB;ECG3B;AACF;ADRA;EACE;IACE,+BAAuB;YAAvB,uBAAuB;ECEzB;EDDA;IACE,iCAAyB;YAAzB,yBAAyB;ECG3B;AACF;;ACmIA;;;;EANE,2BAA2B;EAC3B,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;ADtHnB;;AC2IA;EAfE,6BAD8B;EAE9B,kBAAkB;EAClB,eAAe;EACf,aAAa;EACb,YAAY;EACZ,cAAc;EACd,eAAe;EACf,qBAAqB;EACrB,oBAAoB;EACpB,kBAAkB;EAClB,QAAQ;EACR,iCAAyB;UAAzB,yBAAyB;EACzB,gCAAwB;UAAxB,wBAAwB;EACxB,cAAc;ADxHhB;;AC8HE;;EACE,qBCpHkB;AFNtB;;ACiMA;EAhEE,qBAAqB;EACrB,wBAAwB;EACxB,uCC1K2B;ED2K3B,YAAY;EACZ,uBCxGuB;EDyGvB,eAAe;EACf,oBAAoB;EACpB,qBAAqB;EACrB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,aAAa;EACb,kBAAkB;EAClB,mBAAmB;EACnB,WAAW;AD7Hb;;AC8HE;EAEE,uBClL2B;EDmL3B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,kEAA0D;UAA1D,0DAA0D;EAC1D,uCAA+B;UAA/B,+BAA+B;AD5HnC;;AC6HE;EACE,WAAW;EACX,UAAU;AD1Hd;;AC2HE;EACE,WAAW;EACX,UAAU;ADxHd;;ACyHE;EAEE,uCC9MyB;AFuF7B;;ACwHE;EACE,uCChNyB;AF2F7B;;ACuHE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADpHf;;ACqHE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADlHf;;ACmHE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADhHf;;ACiIA;EAXE,mDAA2C;UAA3C,2CAA2C;EAC3C,yBCrO4B;EDsO5B,uBC1KuB;ED2KvB,+BAA+B;EAC/B,6BAA6B;EAC7B,WAAW;EACX,cAAc;EACd,WAAW;EACX,kBAAkB;EAClB,UAAU;ADlHZ;;AC8HA;;;;;;;;;;;;;;;;;EANE,SADuB;EAEvB,OAFuB;EAGvB,kBAAkB;EAClB,QAJuB;EAKvB,MALuB;AD/FzB;;AGtHA;;;;;EA3BE,qBAAqB;EACrB,wBAAwB;EACxB,mBAAmB;EACnB,6BAA+C;EAC/C,kBDoDU;ECnDV,gBAAgB;EAChB,oBAAoB;EACpB,eDiBW;EChBX,cAfqB;EAgBrB,2BAA2B;EAC3B,gBAhBuB;EAiBvB,mCAfiE;EAgBjE,iCAfmE;EAgBnE,kCAhBmE;EAiBnE,gCAlBiE;EAmBjE,kBAAkB;EAClB,mBAAmB;AHyJrB;;AGvJE;;;;;;;;;;;;;;;;;EAIE,aAAa;AHuKjB;;AGtKE;;;;;;;;;;;;;;;;EAEE,mBAAmB;AHuLvB;;AI5NA,0EAAA;AAEA;;;;;;;;;;;;;;;;;;;;;;;EAuBE,SAAS;EACT,UAAU;AJ8NZ;;AI3NA;;;;;;EAME,eAAe;EACf,mBAAmB;AJ8NrB;;AI3NA;EACE,gBAAgB;AJ8NlB;;AI3NA;;;;EAIE,SAAS;AJ8NX;;AI3NA;EACE,sBAAsB;AJ8NxB;;AI5NA;EAII,mBAAmB;AJ4NvB;;AIzNA;;;;;EAKE,YAAY;EACZ,eAAe;AJ4NjB;;AI1NA;EACE,eAAe;AJ6NjB;;AI1NA;EACE,SAAS;AJ6NX;;AI1NA;EACE,yBAAyB;EACzB,iBAAiB;AJ6NnB;;AI3NA;;EAEE,UAAU;AJ8NZ;;AIhOA;;EAII,gBAAgB;AJiOpB;;AInQA;EClBE,uBHlB6B;EGmB7B,eAhCc;EAiCd,kCAAkC;EAClC,mCAAmC;EACnC,gBAlCoB;EAmCpB,kBAhCsB;EAiCtB,kBAhCsB;EAiCtB,kCApCiC;EAqCjC,8BAAsB;KAAtB,2BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;ALyRxB;;AKvRA;;;;;;;EAOE,cAAc;AL0RhB;;AKxRA;;;;;EAKE,oLH7ByL;AFwT3L;;AKzRA;;EAEE,6BAA6B;EAC7B,4BAA4B;EAC5B,sBHlC0B;AF8T5B;;AK1RA;EACE,cH1D4B;EG2D5B,cAzDkB;EA0DlB,gBH3BiB;EG4BjB,gBAzDoB;ALsVtB;;AKzRA;EACE,cHpDgC;EGqDhC,eAAe;EACf,qBAAqB;AL4RvB;;AK/RA;EAKI,mBAAmB;AL8RvB;;AKnSA;EAOI,cHzE0B;AFyW9B;;AK9RA;EACE,4BHtE4B;EGuE5B,cH5DgC;EG6DhC,kBApEiB;EAqEjB,mBAtEkB;EAuElB,4BAxEgC;ALyWlC;;AK/RA;EACE,4BH7E4B;EG8E5B,YAAY;EACZ,cAAc;EACd,WAvEa;EAwEb,gBAvEkB;ALyWpB;;AKhSA;EACE,YAAY;EACZ,eAAe;ALmSjB;;AKjSA;;EAEE,wBAAwB;ALoS1B;;AKlSA;EACE,kBAtFuB;AL2XzB;;AKnSA;EACE,mBAAmB;EACnB,oBAAoB;ALsStB;;AKpSA;EACE,cHzG4B;EG0G5B,gBHrEe;AF4WjB;;AKnSA;EACE,YAAY;ALsSd;;AKpSA;EJzDE,iCAAiC;EI2DjC,4BH7G4B;EG8G5B,cHnH4B;EGoH5B,kBAhGqB;EAiGrB,gBAAgB;EAChB,uBAjG0B;EAkG1B,gBAAgB;EAChB,iBAAiB;ALuSnB;;AK/SA;EAUI,6BAA6B;EAC7B,mBAAmB;EACnB,cAtGoB;EAuGpB,UAAU;ALySd;;AKvSA;;EAGI,mBAAmB;ALySvB;;AK5SA;;EAKM,gBAAgB;AL4StB;;AKjTA;EAOI,cHvI0B;AFqb9B;;ACxbE;EACE,WAAW;EACX,YAAY;EACZ,cAAc;AD2blB;;AM5bA;EACE,sBAAsB;AN+bxB;;AM7bA;EACE,uBAAuB;ANgczB;;AM5bA;EACE,2BAA2B;AN+b7B;;AMnbI;EACE,0BAA2B;ANsbjC;;AMvbI;EACE,4BAA2B;AN0bjC;;AM3bI;EACE,0BAA2B;AN8bjC;;AM/bI;EACE,4BAA2B;ANkcjC;;AMncI;EACE,6BAA2B;ANscjC;;AMvcI;EACE,0BAA2B;AN0cjC;;AM3cI;EACE,6BAA2B;AN8cjC;;ACxZE;EKvDE;IACE,0BAA2B;ENmd/B;EMpdE;IACE,4BAA2B;ENsd/B;EMvdE;IACE,0BAA2B;ENyd/B;EM1dE;IACE,4BAA2B;EN4d/B;EM7dE;IACE,6BAA2B;EN+d/B;EMheE;IACE,0BAA2B;ENke/B;EMneE;IACE,6BAA2B;ENqe/B;AACF;;AC5aE;EK3DE;IACE,0BAA2B;EN2e/B;EM5eE;IACE,4BAA2B;EN8e/B;EM/eE;IACE,0BAA2B;ENif/B;EMlfE;IACE,4BAA2B;ENof/B;EMrfE;IACE,6BAA2B;ENuf/B;EMxfE;IACE,0BAA2B;EN0f/B;EM3fE;IACE,6BAA2B;EN6f/B;AACF;;AC5bE;EKnEE;IACE,0BAA2B;ENmgB/B;EMpgBE;IACE,4BAA2B;ENsgB/B;EMvgBE;IACE,0BAA2B;ENygB/B;EM1gBE;IACE,4BAA2B;EN4gB/B;EM7gBE;IACE,6BAA2B;EN+gB/B;EMhhBE;IACE,0BAA2B;ENkhB/B;EMnhBE;IACE,6BAA2B;ENqhB/B;AACF;;AChdE;EKvEE;IACE,0BAA2B;EN2hB/B;EM5hBE;IACE,4BAA2B;EN8hB/B;EM/hBE;IACE,0BAA2B;ENiiB/B;EMliBE;IACE,4BAA2B;ENoiB/B;EMriBE;IACE,6BAA2B;ENuiB/B;EMxiBE;IACE,0BAA2B;EN0iB/B;EM3iBE;IACE,6BAA2B;EN6iB/B;AACF;;ACzdI;EKtFA;IACE,0BAA2B;ENmjB/B;EMpjBE;IACE,4BAA2B;ENsjB/B;EMvjBE;IACE,0BAA2B;ENyjB/B;EM1jBE;IACE,4BAA2B;EN4jB/B;EM7jBE;IACE,6BAA2B;EN+jB/B;EMhkBE;IACE,0BAA2B;ENkkB/B;EMnkBE;IACE,6BAA2B;ENqkB/B;AACF;;ACleI;EKrGA;IACE,0BAA2B;EN2kB/B;EM5kBE;IACE,4BAA2B;EN8kB/B;EM/kBE;IACE,0BAA2B;ENilB/B;EMllBE;IACE,4BAA2B;ENolB/B;EMrlBE;IACE,6BAA2B;ENulB/B;EMxlBE;IACE,0BAA2B;EN0lB/B;EM3lBE;IACE,6BAA2B;EN6lB/B;AACF;;AMrkBE;EACE,6BAAqC;ANwkBzC;;AMzkBE;EACE,8BAAqC;AN4kBzC;;AM7kBE;EACE,2BAAqC;ANglBzC;;AMjlBE;EACE,4BAAqC;ANolBzC;;ACxjBE;EKxBE;IACE,6BAAqC;ENolBzC;AACF;;AC1jBE;EKzBE;IACE,6BAAqC;ENulBzC;AACF;;AC5jBE;EK1BE;IACE,6BAAqC;EN0lBzC;AACF;;AC9jBE;EK3BE;IACE,6BAAqC;EN6lBzC;AACF;;AChkBE;EK5BE;IACE,6BAAqC;ENgmBzC;AACF;;ACjkBI;EK9BA;IACE,6BAAqC;ENmmBzC;AACF;;AC7jBI;EKrCA;IACE,6BAAqC;ENsmBzC;AACF;;AC9jBI;EKvCA;IACE,6BAAqC;ENymBzC;AACF;;AC1jBI;EK9CA;IACE,6BAAqC;EN4mBzC;AACF;;AC9mBE;EKxBE;IACE,8BAAqC;EN0oBzC;AACF;;AChnBE;EKzBE;IACE,8BAAqC;EN6oBzC;AACF;;AClnBE;EK1BE;IACE,8BAAqC;ENgpBzC;AACF;;ACpnBE;EK3BE;IACE,8BAAqC;ENmpBzC;AACF;;ACtnBE;EK5BE;IACE,8BAAqC;ENspBzC;AACF;;ACvnBI;EK9BA;IACE,8BAAqC;ENypBzC;AACF;;ACnnBI;EKrCA;IACE,8BAAqC;EN4pBzC;AACF;;ACpnBI;EKvCA;IACE,8BAAqC;EN+pBzC;AACF;;AChnBI;EK9CA;IACE,8BAAqC;ENkqBzC;AACF;;ACpqBE;EKxBE;IACE,2BAAqC;ENgsBzC;AACF;;ACtqBE;EKzBE;IACE,2BAAqC;ENmsBzC;AACF;;ACxqBE;EK1BE;IACE,2BAAqC;ENssBzC;AACF;;AC1qBE;EK3BE;IACE,2BAAqC;ENysBzC;AACF;;AC5qBE;EK5BE;IACE,2BAAqC;EN4sBzC;AACF;;AC7qBI;EK9BA;IACE,2BAAqC;EN+sBzC;AACF;;ACzqBI;EKrCA;IACE,2BAAqC;ENktBzC;AACF;;AC1qBI;EKvCA;IACE,2BAAqC;ENqtBzC;AACF;;ACtqBI;EK9CA;IACE,2BAAqC;ENwtBzC;AACF;;AC1tBE;EKxBE;IACE,4BAAqC;ENsvBzC;AACF;;AC5tBE;EKzBE;IACE,4BAAqC;ENyvBzC;AACF;;AC9tBE;EK1BE;IACE,4BAAqC;EN4vBzC;AACF;;AChuBE;EK3BE;IACE,4BAAqC;EN+vBzC;AACF;;ACluBE;EK5BE;IACE,4BAAqC;ENkwBzC;AACF;;ACnuBI;EK9BA;IACE,4BAAqC;ENqwBzC;AACF;;AC/tBI;EKrCA;IACE,4BAAqC;ENwwBzC;AACF;;AChuBI;EKvCA;IACE,4BAAqC;EN2wBzC;AACF;;AC5tBI;EK9CA;IACE,4BAAqC;EN8wBzC;AACF;;AM7wBA;EACE,qCAAqC;ANgxBvC;;AM9wBA;EACE,oCAAoC;ANixBtC;;AM/wBA;EACE,oCAAoC;ANkxBtC;;AMhxBA;EACE,6BAA6B;ANmxB/B;;AM/wBE;EACE,uBAAwB;ANkxB5B;;AMjxBE;EAGI,yBAAqC;ANkxB3C;;AMjxBE;EACE,kCAAmC;ANoxBvC;;AM3xBE;EACE,yBAAwB;AN8xB5B;;AM7xBE;EAGI,uBAAqC;AN8xB3C;;AM7xBE;EACE,oCAAmC;ANgyBvC;;AMvyBE;EACE,4BAAwB;AN0yB5B;;AMzyBE;EAGI,yBAAqC;AN0yB3C;;AMzyBE;EACE,uCAAmC;AN4yBvC;;AMnzBE;EACE,yBAAwB;ANszB5B;;AMrzBE;EAGI,yBAAqC;ANszB3C;;AMrzBE;EACE,oCAAmC;ANwzBvC;;AM/zBE;EACE,yBAAwB;ANk0B5B;;AMj0BE;EAGI,yBAAqC;ANk0B3C;;AMj0BE;EACE,oCAAmC;ANo0BvC;;AM30BE;EACE,yBAAwB;AN80B5B;;AM70BE;EAGI,yBAAqC;AN80B3C;;AM70BE;EACE,oCAAmC;ANg1BvC;;AMv1BE;EACE,yBAAwB;AN01B5B;;AMz1BE;EAGI,yBAAqC;AN01B3C;;AMz1BE;EACE,oCAAmC;AN41BvC;;AMn2BE;EACE,yBAAwB;ANs2B5B;;AMr2BE;EAGI,yBAAqC;ANs2B3C;;AMr2BE;EACE,oCAAmC;ANw2BvC;;AM/2BE;EACE,yBAAwB;ANk3B5B;;AMj3BE;EAGI,yBAAqC;ANk3B3C;;AMj3BE;EACE,oCAAmC;ANo3BvC;;AM33BE;EACE,yBAAwB;AN83B5B;;AM73BE;EAGI,yBAAqC;AN83B3C;;AM73BE;EACE,oCAAmC;ANg4BvC;;AM73BE;EACE,yBAAwB;ANg4B5B;;AM/3BE;EACE,oCAAmC;ANk4BvC;;AMr4BE;EACE,yBAAwB;ANw4B5B;;AMv4BE;EACE,oCAAmC;AN04BvC;;AM74BE;EACE,yBAAwB;ANg5B5B;;AM/4BE;EACE,oCAAmC;ANk5BvC;;AMr5BE;EACE,yBAAwB;ANw5B5B;;AMv5BE;EACE,oCAAmC;AN05BvC;;AM75BE;EACE,yBAAwB;ANg6B5B;;AM/5BE;EACE,oCAAmC;ANk6BvC;;AMr6BE;EACE,yBAAwB;ANw6B5B;;AMv6BE;EACE,oCAAmC;AN06BvC;;AM76BE;EACE,yBAAwB;ANg7B5B;;AM/6BE;EACE,oCAAmC;ANk7BvC;;AMr7BE;EACE,4BAAwB;ANw7B5B;;AMv7BE;EACE,uCAAmC;AN07BvC;;AM77BE;EACE,yBAAwB;ANg8B5B;;AM/7BE;EACE,oCAAmC;ANk8BvC;;AMh8BA;EACE,2BAAqC;ANm8BvC;;AMl8BA;EACE,2BAAsC;ANq8BxC;;AMp8BA;EACE,2BAAsC;ANu8BxC;;AMt8BA;EACE,2BAAwC;ANy8B1C;;AMx8BA;EACE,2BAAoC;AN28BtC;;AMz8BA;EACE,+LAAuC;AN48BzC;;AM18BA;EACE,+LAAyC;AN68B3C;;AM38BA;EACE,+LAA0C;AN88B5C;;AM58BA;EACE,iCAAyC;AN+8B3C;;AM78BA;EACE,iCAAoC;ANg9BtC;;AMz8BE;EACE,yBAA+B;AN48BnC;;AC5gCE;EKkEE;IACE,yBAA+B;EN88BnC;AACF;;AC9gCE;EKiEE;IACE,yBAA+B;ENi9BnC;AACF;;AChhCE;EKgEE;IACE,yBAA+B;ENo9BnC;AACF;;AClhCE;EK+DE;IACE,yBAA+B;ENu9BnC;AACF;;ACphCE;EK8DE;IACE,yBAA+B;EN09BnC;AACF;;ACrhCI;EK4DA;IACE,yBAA+B;EN69BnC;AACF;;ACjhCI;EKqDA;IACE,yBAA+B;ENg+BnC;AACF;;AClhCI;EKmDA;IACE,yBAA+B;ENm+BnC;AACF;;AC9gCI;EK4CA;IACE,yBAA+B;ENs+BnC;AACF;;AMngCE;EACE,wBAA+B;ANsgCnC;;ACtkCE;EKkEE;IACE,wBAA+B;ENwgCnC;AACF;;ACxkCE;EKiEE;IACE,wBAA+B;EN2gCnC;AACF;;AC1kCE;EKgEE;IACE,wBAA+B;EN8gCnC;AACF;;AC5kCE;EK+DE;IACE,wBAA+B;ENihCnC;AACF;;AC9kCE;EK8DE;IACE,wBAA+B;ENohCnC;AACF;;AC/kCI;EK4DA;IACE,wBAA+B;ENuhCnC;AACF;;AC3kCI;EKqDA;IACE,wBAA+B;EN0hCnC;AACF;;AC5kCI;EKmDA;IACE,wBAA+B;EN6hCnC;AACF;;ACxkCI;EK4CA;IACE,wBAA+B;ENgiCnC;AACF;;AM7jCE;EACE,0BAA+B;ANgkCnC;;AChoCE;EKkEE;IACE,0BAA+B;ENkkCnC;AACF;;ACloCE;EKiEE;IACE,0BAA+B;ENqkCnC;AACF;;ACpoCE;EKgEE;IACE,0BAA+B;ENwkCnC;AACF;;ACtoCE;EK+DE;IACE,0BAA+B;EN2kCnC;AACF;;ACxoCE;EK8DE;IACE,0BAA+B;EN8kCnC;AACF;;ACzoCI;EK4DA;IACE,0BAA+B;ENilCnC;AACF;;ACroCI;EKqDA;IACE,0BAA+B;ENolCnC;AACF;;ACtoCI;EKmDA;IACE,0BAA+B;ENulCnC;AACF;;ACloCI;EK4CA;IACE,0BAA+B;EN0lCnC;AACF;;AMvnCE;EACE,gCAA+B;AN0nCnC;;AC1rCE;EKkEE;IACE,gCAA+B;EN4nCnC;AACF;;AC5rCE;EKiEE;IACE,gCAA+B;EN+nCnC;AACF;;AC9rCE;EKgEE;IACE,gCAA+B;ENkoCnC;AACF;;AChsCE;EK+DE;IACE,gCAA+B;ENqoCnC;AACF;;AClsCE;EK8DE;IACE,gCAA+B;ENwoCnC;AACF;;ACnsCI;EK4DA;IACE,gCAA+B;EN2oCnC;AACF;;AC/rCI;EKqDA;IACE,gCAA+B;EN8oCnC;AACF;;AChsCI;EKmDA;IACE,gCAA+B;ENipCnC;AACF;;AC5rCI;EK4CA;IACE,gCAA+B;ENopCnC;AACF;;AMjrCE;EACE,+BAA+B;ANorCnC;;ACpvCE;EKkEE;IACE,+BAA+B;ENsrCnC;AACF;;ACtvCE;EKiEE;IACE,+BAA+B;ENyrCnC;AACF;;ACxvCE;EKgEE;IACE,+BAA+B;EN4rCnC;AACF;;AC1vCE;EK+DE;IACE,+BAA+B;EN+rCnC;AACF;;AC5vCE;EK8DE;IACE,+BAA+B;ENksCnC;AACF;;AC7vCI;EK4DA;IACE,+BAA+B;ENqsCnC;AACF;;ACzvCI;EKqDA;IACE,+BAA+B;ENwsCnC;AACF;;AC1vCI;EKmDA;IACE,+BAA+B;EN2sCnC;AACF;;ACtvCI;EK4CA;IACE,+BAA+B;EN8sCnC;AACF;;AM7sCA;EACE,wBAAwB;ANgtC1B;;AM9sCA;EACE,uBAAuB;EACvB,iCAAiC;EACjC,yBAAyB;EACzB,2BAA2B;EAC3B,qBAAqB;EACrB,6BAA6B;EAC7B,8BAA8B;EAC9B,wBAAwB;ANitC1B;;ACzzCE;EK2GA;IACE,wBAAwB;ENktC1B;AACF;;AC3zCE;EK2GA;IACE,wBAAwB;ENotC1B;AACF;;AC7zCE;EK2GA;IACE,wBAAwB;ENstC1B;AACF;;AC/zCE;EK2GA;IACE,wBAAwB;ENwtC1B;AACF;;ACj0CE;EK2GA;IACE,wBAAwB;EN0tC1B;AACF;;ACl0CI;EK0GF;IACE,wBAAwB;EN4tC1B;AACF;;AC9zCI;EKoGF;IACE,wBAAwB;EN8tC1B;AACF;;AC/zCI;EKmGF;IACE,wBAAwB;ENguC1B;AACF;;AC3zCI;EK6FF;IACE,wBAAwB;ENkuC1B;AACF;;AMjuCA;EACE,6BAA6B;ANouC/B;;ACn3CE;EKkJA;IACE,6BAA6B;ENquC/B;AACF;;ACr3CE;EKkJA;IACE,6BAA6B;ENuuC/B;AACF;;ACv3CE;EKkJA;IACE,6BAA6B;ENyuC/B;AACF;;ACz3CE;EKkJA;IACE,6BAA6B;EN2uC/B;AACF;;AC33CE;EKkJA;IACE,6BAA6B;EN6uC/B;AACF;;AC53CI;EKiJF;IACE,6BAA6B;EN+uC/B;AACF;;ACx3CI;EK2IF;IACE,6BAA6B;ENivC/B;AACF;;ACz3CI;EK0IF;IACE,6BAA6B;ENmvC/B;AACF;;ACr3CI;EKoIF;IACE,6BAA6B;ENqvC/B;AACF;;AMlvCA;EACE,oBAAoB;ANqvCtB;;AMnvCA;EACE,qBAAqB;ANsvCvB;;AMpvCA;EACE,2BAA2B;ANuvC7B;;AMrvCA;EACE,2BAA2B;ANwvC7B;;AMnvCA;EACE,6BAA6B;ANsvC/B;;AOrgDA;EAEE,uBLG6B;EKF7B,kBLyDgB;EKxDhB,4ELX2B;EKY3B,cLP4B;EKQ5B,cAAc;EACd,gBAZmB;APmhDrB;;AOrgDA;EAGI,8DLA8B;AFsgDlC;;AOzgDA;EAKI,oELF8B;AF0gDlC;;AQl/CA;EAGE,uBNlC6B;EMmC7B,qBNvC4B;EMwC5B,iBL/CwB;EKgDxB,cN7C4B;EM8C5B,eAAe;EAGf,uBAAuB;EACvB,mCAjD+D;EAkD/D,oBAjDgC;EAkDhC,qBAlDgC;EAmDhC,gCApD+D;EAqD/D,kBAAkB;EAClB,mBAAmB;ARi/CrB;;AQjgDA;EAkBI,cAAc;ARm/ClB;;AQrgDA;EAwBM,aAAa;EACb,YAAY;ARi/ClB;;AQ1gDA;EA2BM,iCAAqD;EACrD,sBAAsB;ARm/C5B;;AQ/gDA;EA8BM,qBAAqB;EACrB,kCAAsD;ARq/C5D;;AQphDA;EAiCM,iCAAqD;EACrD,kCAAsD;ARu/C5D;;AQzhDA;EAsCI,qBN1E0B;EM2E1B,cN9E0B;AFqkD9B;;AQ9hDA;EA0CI,qBNlE8B;EMmE9B,cNlF0B;AF0kD9B;;AQniDA;EA6CM,kDNrE4B;AF+jDlC;;AQviDA;EAgDI,qBNtF0B;EMuF1B,cNxF0B;AFmlD9B;;AQ5iDA;EAoDI,6BAA6B;EAC7B,yBAAyB;EACzB,cN5F0B;EM6F1B,0BAA0B;AR4/C9B;;AQnjDA;EA4DM,4BN7FwB;EM8FxB,cNpGwB;AF+lD9B;;AQxjDA;EAgEM,yBAAiE;EACjE,cNxGwB;AFomD9B;;AQ7jDA;;EAoEM,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;AR8/CtB;;AQpkDA;EA2EM,uBN1GyB;EM2GzB,yBAAyB;EACzB,cNxHuB;AFqnD7B;;AQ1kDA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,cN7HqB;AF2nD7B;;AQhlDA;EAqFQ,yBAAyB;EACzB,cNjIqB;AFgoD7B;;AQrlDA;EAwFU,mDNvHqB;AFwnD/B;;AQzlDA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,cNxIqB;AF0oD7B;;AQ/lDA;;EAgGQ,uBN/HuB;EMgIvB,yBAAyB;EACzB,gBAAgB;ARogDxB;;AQtmDA;EAoGQ,yBN/IqB;EMgJrB,YNpIuB;AF0oD/B;;AQ3mDA;EAwGU,uBAA2C;ARugDrD;;AQ/mDA;;EA2GU,yBNtJmB;EMuJnB,yBAAyB;EACzB,gBAAgB;EAChB,YN7IqB;AFspD/B;;AQvnDA;EAiHU,gEAA4E;AR0gDtF;;AQ3nDA;EAmHQ,6BAA6B;EAC7B,mBNnJuB;EMoJvB,YNpJuB;AFgqD/B;;AQjoDA;EA0HU,uBNzJqB;EM0JrB,mBN1JqB;EM2JrB,cNvKmB;AFkrD7B;;AQvoDA;EA+HY,4DAA8D;AR4gD1E;;AQ3oDA;EAqIc,gEAA4E;AR0gD1F;;AQ/oDA;;EAwIU,6BAA6B;EAC7B,mBNxKqB;EMyKrB,gBAAgB;EAChB,YN1KqB;AFsrD/B;;AQvpDA;EA6IQ,6BAA6B;EAC7B,qBNzLqB;EM0LrB,cN1LqB;AFwsD7B;;AQ7pDA;EAoJU,yBN/LmB;EMgMnB,YNpLqB;AFisD/B;;AQlqDA;EA4Jc,4DAA8D;AR0gD5E;;AQtqDA;;EA+JU,6BAA6B;EAC7B,qBN3MmB;EM4MnB,gBAAgB;EAChB,cN7MmB;AFytD7B;;AQ9qDA;EA2EM,yBNtHuB;EMuHvB,yBAAyB;EACzB,YN5GyB;AFmtD/B;;AQprDA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,YNjHuB;AFytD/B;;AQ1rDA;EAqFQ,yBAAyB;EACzB,YNrHuB;AF8tD/B;;AQ/rDA;EAwFU,gDNnImB;AF8uD7B;;AQnsDA;EA2FQ,uBAAoC;EACpC,yBAAyB;EACzB,YN5HuB;AFwuD/B;;AQzsDA;;EAgGQ,yBN3IqB;EM4IrB,yBAAyB;EACzB,gBAAgB;AR8mDxB;;AQhtDA;EAoGQ,uBNnIuB;EMoIvB,cNhJqB;AFgwD7B;;AQrtDA;EAwGU,yBAA2C;ARinDrD;;AQztDA;;EA2GU,uBN1IqB;EM2IrB,yBAAyB;EACzB,gBAAgB;EAChB,cNzJmB;AF4wD7B;;AQjuDA;EAiHU,4DAA4E;ARonDtF;;AQruDA;EAmHQ,6BAA6B;EAC7B,qBN/JqB;EMgKrB,cNhKqB;AFsxD7B;;AQ3uDA;EA0HU,yBNrKmB;EMsKnB,qBNtKmB;EMuKnB,YN3JqB;AFgxD/B;;AQjvDA;EA+HY,gEAA8D;ARsnD1E;;AQrvDA;EAqIc,4DAA4E;ARonD1F;;AQzvDA;;EAwIU,6BAA6B;EAC7B,qBNpLmB;EMqLnB,gBAAgB;EAChB,cNtLmB;AF4yD7B;;AQjwDA;EA6IQ,6BAA6B;EAC7B,mBN7KuB;EM8KvB,YN9KuB;AFsyD/B;;AQvwDA;EAoJU,uBNnLqB;EMoLrB,cNhMmB;AFuzD7B;;AQ5wDA;EA4Jc,gEAA8D;ARonD5E;;AQhxDA;;EA+JU,6BAA6B;EAC7B,mBN/LqB;EMgMrB,gBAAgB;EAChB,YNjMqB;AFuzD/B;;AQxxDA;EA2EM,4BN5GwB;EM6GxB,yBAAyB;EACzB,cNpHwB;AFq0D9B;;AQ9xDA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,cNzHsB;AF20D9B;;AQpyDA;EAqFQ,yBAAyB;EACzB,cN7HsB;AFg1D9B;;AQzyDA;EAwFU,mDNzHoB;AF80D9B;;AQ7yDA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,cNpIsB;AF01D9B;;AQnzDA;;EAgGQ,4BNjIsB;EMkItB,yBAAyB;EACzB,gBAAgB;ARwtDxB;;AQ1zDA;EAoGQ,yBN3IsB;EM4ItB,iBNtIsB;AFg2D9B;;AQ/zDA;EAwGU,yBAA2C;AR2tDrD;;AQn0DA;;EA2GU,yBNlJoB;EMmJpB,yBAAyB;EACzB,gBAAgB;EAChB,iBN/IoB;AF42D9B;;AQ30DA;EAiHU,gEAA4E;AR8tDtF;;AQ/0DA;EAmHQ,6BAA6B;EAC7B,wBNrJsB;EMsJtB,iBNtJsB;AFs3D9B;;AQr1DA;EA0HU,4BN3JoB;EM4JpB,wBN5JoB;EM6JpB,cNnKoB;AFk4D9B;;AQ31DA;EA+HY,sEAA8D;ARguD1E;;AQ/1DA;EAqIc,gEAA4E;AR8tD1F;;AQn2DA;;EAwIU,6BAA6B;EAC7B,wBN1KoB;EM2KpB,gBAAgB;EAChB,iBN5KoB;AF44D9B;;AQ32DA;EA6IQ,6BAA6B;EAC7B,qBNrLsB;EMsLtB,cNtLsB;AFw5D9B;;AQj3DA;EAoJU,yBN3LoB;EM4LpB,iBNtLoB;AFu5D9B;;AQt3DA;EA4Jc,sEAA8D;AR8tD5E;;AQ13DA;;EA+JU,6BAA6B;EAC7B,qBNvMoB;EMwMpB,gBAAgB;EAChB,cNzMoB;AFy6D9B;;AQl4DA;EA2EM,yBNlHwB;EMmHxB,yBAAyB;EACzB,iBN9GwB;AFy6D9B;;AQx4DA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,iBNnHsB;AF+6D9B;;AQ94DA;EAqFQ,yBAAyB;EACzB,iBNvHsB;AFo7D9B;;AQn5DA;EAwFU,gDN/HoB;AF87D9B;;AQv5DA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,iBN9HsB;AF87D9B;;AQ75DA;;EAgGQ,yBNvIsB;EMwItB,yBAAyB;EACzB,gBAAgB;ARk0DxB;;AQp6DA;EAoGQ,4BNrIsB;EMsItB,cN5IsB;AFg9D9B;;AQz6DA;EAwGU,yBAA2C;ARq0DrD;;AQ76DA;;EA2GU,4BN5IoB;EM6IpB,yBAAyB;EACzB,gBAAgB;EAChB,cNrJoB;AF49D9B;;AQr7DA;EAiHU,sEAA4E;ARw0DtF;;AQz7DA;EAmHQ,6BAA6B;EAC7B,qBN3JsB;EM4JtB,cN5JsB;AFs+D9B;;AQ/7DA;EA0HU,yBNjKoB;EMkKpB,qBNlKoB;EMmKpB,iBN7JoB;AFs+D9B;;AQr8DA;EA+HY,gEAA8D;AR00D1E;;AQz8DA;EAqIc,sEAA4E;ARw0D1F;;AQ78DA;;EAwIU,6BAA6B;EAC7B,qBNhLoB;EMiLpB,gBAAgB;EAChB,cNlLoB;AF4/D9B;;AQr9DA;EA6IQ,6BAA6B;EAC7B,wBN/KsB;EMgLtB,iBNhLsB;AF4/D9B;;AQ39DA;EAoJU,4BNrLoB;EMsLpB,cN5LoB;AFugE9B;;AQh+DA;EA4Jc,gEAA8D;ARw0D5E;;AQp+DA;;EA+JU,6BAA6B;EAC7B,wBNjMoB;EMkMpB,gBAAgB;EAChB,iBNnMoB;AF6gE9B;;AQ5+DA;EA2EM,yBNrG4B;EMsG5B,yBAAyB;EACzB,WC7DU;ATk+DhB;;AQl/DA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,WClEQ;ATw+DhB;;AQx/DA;EAqFQ,yBAAyB;EACzB,WCtEQ;AT6+DhB;;AQ7/DA;EAwFU,iDNlHwB;AF2hElC;;AQjgEA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,WC7EQ;ATu/DhB;;AQvgEA;;EAgGQ,yBN1H0B;EM2H1B,yBAAyB;EACzB,gBAAgB;AR46DxB;;AQ9gEA;EAoGQ,sBCpFQ;EDqFR,cN/H0B;AF6iElC;;AQnhEA;EAwGU,yBAA2C;AR+6DrD;;AQvhEA;;EA2GU,sBC3FM;ED4FN,yBAAyB;EACzB,gBAAgB;EAChB,cNxIwB;AFyjElC;;AQ/hEA;EAiHU,0DAA4E;ARk7DtF;;AQniEA;EAmHQ,6BAA6B;EAC7B,qBN9I0B;EM+I1B,cN/I0B;AFmkElC;;AQziEA;EA0HU,yBNpJwB;EMqJxB,qBNrJwB;EMsJxB,WC5GM;AT+hEhB;;AQ/iEA;EA+HY,gEAA8D;ARo7D1E;;AQnjEA;EAqIc,0DAA4E;ARk7D1F;;AQvjEA;;EAwIU,6BAA6B;EAC7B,qBNnKwB;EMoKxB,gBAAgB;EAChB,cNrKwB;AFylElC;;AQ/jEA;EA6IQ,6BAA6B;EAC7B,kBC9HQ;ED+HR,WC/HQ;ATqjEhB;;AQrkEA;EAoJU,sBCpIM;EDqIN,cN/KwB;AFomElC;;AQ1kEA;EA4Jc,gEAA8D;ARk7D5E;;AQ9kEA;;EA+JU,6BAA6B;EAC7B,kBChJM;EDiJN,gBAAgB;EAChB,WClJM;ATskEhB;;AQtlEA;EA2EM,yBNnG4B;EMoG5B,yBAAyB;EACzB,WC7DU;AT4kEhB;;AQ5lEA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,WClEQ;ATklEhB;;AQlmEA;EAqFQ,yBAAyB;EACzB,WCtEQ;ATulEhB;;AQvmEA;EAwFU,kDNhHwB;AFmoElC;;AQ3mEA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,WC7EQ;ATimEhB;;AQjnEA;;EAgGQ,yBNxH0B;EMyH1B,yBAAyB;EACzB,gBAAgB;ARshExB;;AQxnEA;EAoGQ,sBCpFQ;EDqFR,cN7H0B;AFqpElC;;AQ7nEA;EAwGU,yBAA2C;ARyhErD;;AQjoEA;;EA2GU,sBC3FM;ED4FN,yBAAyB;EACzB,gBAAgB;EAChB,cNtIwB;AFiqElC;;AQzoEA;EAiHU,0DAA4E;AR4hEtF;;AQ7oEA;EAmHQ,6BAA6B;EAC7B,qBN5I0B;EM6I1B,cN7I0B;AF2qElC;;AQnpEA;EA0HU,yBNlJwB;EMmJxB,qBNnJwB;EMoJxB,WC5GM;ATyoEhB;;AQzpEA;EA+HY,gEAA8D;AR8hE1E;;AQ7pEA;EAqIc,0DAA4E;AR4hE1F;;AQjqEA;;EAwIU,6BAA6B;EAC7B,qBNjKwB;EMkKxB,gBAAgB;EAChB,cNnKwB;AFisElC;;AQzqEA;EA6IQ,6BAA6B;EAC7B,kBC9HQ;ED+HR,WC/HQ;AT+pEhB;;AQ/qEA;EAoJU,sBCpIM;EDqIN,cN7KwB;AF4sElC;;AQprEA;EA4Jc,gEAA8D;AR4hE5E;;AQxrEA;;EA+JU,6BAA6B;EAC7B,kBChJM;EDiJN,gBAAgB;EAChB,WClJM;ATgrEhB;;AQhsEA;EA2EM,yBNpG4B;EMqG5B,yBAAyB;EACzB,WC7DU;ATsrEhB;;AQtsEA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,WClEQ;AT4rEhB;;AQ5sEA;EAqFQ,yBAAyB;EACzB,WCtEQ;ATisEhB;;AQjtEA;EAwFU,kDNjHwB;AF8uElC;;AQrtEA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,WC7EQ;AT2sEhB;;AQ3tEA;;EAgGQ,yBNzH0B;EM0H1B,yBAAyB;EACzB,gBAAgB;ARgoExB;;AQluEA;EAoGQ,sBCpFQ;EDqFR,cN9H0B;AFgwElC;;AQvuEA;EAwGU,yBAA2C;ARmoErD;;AQ3uEA;;EA2GU,sBC3FM;ED4FN,yBAAyB;EACzB,gBAAgB;EAChB,cNvIwB;AF4wElC;;AQnvEA;EAiHU,0DAA4E;ARsoEtF;;AQvvEA;EAmHQ,6BAA6B;EAC7B,qBN7I0B;EM8I1B,cN9I0B;AFsxElC;;AQ7vEA;EA0HU,yBNnJwB;EMoJxB,qBNpJwB;EMqJxB,WC5GM;ATmvEhB;;AQnwEA;EA+HY,gEAA8D;ARwoE1E;;AQvwEA;EAqIc,0DAA4E;ARsoE1F;;AQ3wEA;;EAwIU,6BAA6B;EAC7B,qBNlKwB;EMmKxB,gBAAgB;EAChB,cNpKwB;AF4yElC;;AQnxEA;EA6IQ,6BAA6B;EAC7B,kBC9HQ;ED+HR,WC/HQ;ATywEhB;;AQzxEA;EAoJU,sBCpIM;EDqIN,cN9KwB;AFuzElC;;AQ9xEA;EA4Jc,gEAA8D;ARsoE5E;;AQlyEA;;EA+JU,6BAA6B;EAC7B,kBChJM;EDiJN,gBAAgB;EAChB,WClJM;AT0xEhB;;AQ1yEA;EA2EM,yBNtG4B;EMuG5B,yBAAyB;EACzB,WC7DU;ATgyEhB;;AQhzEA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,WClEQ;ATsyEhB;;AQtzEA;EAqFQ,yBAAyB;EACzB,WCtEQ;AT2yEhB;;AQ3zEA;EAwFU,iDNnHwB;AF01ElC;;AQ/zEA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,WC7EQ;ATqzEhB;;AQr0EA;;EAgGQ,yBN3H0B;EM4H1B,yBAAyB;EACzB,gBAAgB;AR0uExB;;AQ50EA;EAoGQ,sBCpFQ;EDqFR,cNhI0B;AF42ElC;;AQj1EA;EAwGU,yBAA2C;AR6uErD;;AQr1EA;;EA2GU,sBC3FM;ED4FN,yBAAyB;EACzB,gBAAgB;EAChB,cNzIwB;AFw3ElC;;AQ71EA;EAiHU,0DAA4E;ARgvEtF;;AQj2EA;EAmHQ,6BAA6B;EAC7B,qBN/I0B;EMgJ1B,cNhJ0B;AFk4ElC;;AQv2EA;EA0HU,yBNrJwB;EMsJxB,qBNtJwB;EMuJxB,WC5GM;AT61EhB;;AQ72EA;EA+HY,gEAA8D;ARkvE1E;;AQj3EA;EAqIc,0DAA4E;ARgvE1F;;AQr3EA;;EAwIU,6BAA6B;EAC7B,qBNpKwB;EMqKxB,gBAAgB;EAChB,cNtKwB;AFw5ElC;;AQ73EA;EA6IQ,6BAA6B;EAC7B,kBC9HQ;ED+HR,WC/HQ;ATm3EhB;;AQn4EA;EAoJU,sBCpIM;EDqIN,cNhLwB;AFm6ElC;;AQx4EA;EA4Jc,gEAA8D;ARgvE5E;;AQ54EA;;EA+JU,6BAA6B;EAC7B,kBChJM;EDiJN,gBAAgB;EAChB,WClJM;ATo4EhB;;AQp5EA;EA2EM,yBNvG4B;EMwG5B,yBAAyB;EACzB,yBC/De;AT44ErB;;AQ15EA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,yBCpEa;ATk5ErB;;AQh6EA;EAqFQ,yBAAyB;EACzB,yBCxEa;ATu5ErB;;AQr6EA;EAwFU,kDNpHwB;AFq8ElC;;AQz6EA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,yBC/Ea;ATi6ErB;;AQ/6EA;;EAgGQ,yBN5H0B;EM6H1B,yBAAyB;EACzB,gBAAgB;ARo1ExB;;AQt7EA;EAoGQ,oCCtFa;EDuFb,cNjI0B;AFu9ElC;;AQ37EA;EAwGU,oCAA2C;ARu1ErD;;AQ/7EA;;EA2GU,oCC7FW;ED8FX,yBAAyB;EACzB,gBAAgB;EAChB,cN1IwB;AFm+ElC;;AQv8EA;EAiHU,sFAA4E;AR01EtF;;AQ38EA;EAmHQ,6BAA6B;EAC7B,qBNhJ0B;EMiJ1B,cNjJ0B;AF6+ElC;;AQj9EA;EA0HU,yBNtJwB;EMuJxB,qBNvJwB;EMwJxB,yBC9GW;ATy8ErB;;AQv9EA;EA+HY,gEAA8D;AR41E1E;;AQ39EA;EAqIc,sFAA4E;AR01E1F;;AQ/9EA;;EAwIU,6BAA6B;EAC7B,qBNrKwB;EMsKxB,gBAAgB;EAChB,cNvKwB;AFmgFlC;;AQv+EA;EA6IQ,6BAA6B;EAC7B,gCChIa;EDiIb,yBCjIa;AT+9ErB;;AQ7+EA;EAoJU,oCCtIW;EDuIX,cNjLwB;AF8gFlC;;AQl/EA;EA4Jc,gEAA8D;AR01E5E;;AQt/EA;;EA+JU,6BAA6B;EAC7B,gCClJW;EDmJX,gBAAgB;EAChB,yBCpJW;ATg/ErB;;AQ9/EA;EA2EM,yBNjG4B;EMkG5B,yBAAyB;EACzB,WC7DU;ATo/EhB;;AQpgFA;EAgFQ,yBAAsC;EACtC,yBAAyB;EACzB,WClEQ;AT0/EhB;;AQ1gFA;EAqFQ,yBAAyB;EACzB,WCtEQ;AT+/EhB;;AQ/gFA;EAwFU,iDN9GwB;AFyiFlC;;AQnhFA;EA2FQ,yBAAoC;EACpC,yBAAyB;EACzB,WC7EQ;ATygFhB;;AQzhFA;;EAgGQ,yBNtH0B;EMuH1B,yBAAyB;EACzB,gBAAgB;AR87ExB;;AQhiFA;EAoGQ,sBCpFQ;EDqFR,cN3H0B;AF2jFlC;;AQriFA;EAwGU,yBAA2C;ARi8ErD;;AQziFA;;EA2GU,sBC3FM;ED4FN,yBAAyB;EACzB,gBAAgB;EAChB,cNpIwB;AFukFlC;;AQjjFA;EAiHU,0DAA4E;ARo8EtF;;AQrjFA;EAmHQ,6BAA6B;EAC7B,qBN1I0B;EM2I1B,cN3I0B;AFilFlC;;AQ3jFA;EA0HU,yBNhJwB;EMiJxB,qBNjJwB;EMkJxB,WC5GM;ATijFhB;;AQjkFA;EA+HY,gEAA8D;ARs8E1E;;AQrkFA;EAqIc,0DAA4E;ARo8E1F;;AQzkFA;;EAwIU,6BAA6B;EAC7B,qBN/JwB;EMgKxB,gBAAgB;EAChB,cNjKwB;AFumFlC;;AQjlFA;EA6IQ,6BAA6B;EAC7B,kBC9HQ;ED+HR,WC/HQ;ATukFhB;;AQvlFA;EAoJU,sBCpIM;EDqIN,cN3KwB;AFknFlC;;AQ5lFA;EA4Jc,gEAA8D;ARo8E5E;;AQhmFA;;EA+JU,6BAA6B;EAC7B,kBChJM;EDiJN,gBAAgB;EAChB,WClJM;ATwlFhB;;AQxmFA;EATE,kBN+BgB;EM9BhB,kBNAc;AFqnFhB;;AQ7mFA;EANE,eNHW;AF0nFb;;AQjnFA;EAJE,kBNNc;AF+nFhB;;AQrnFA;EAFE,iBNTa;AFooFf;;AQznFA;;EA+KI,uBN9M2B;EM+M3B,qBNnN0B;EMoN1B,gBAnMyB;EAoMzB,YAnMyB;ARkpF7B;;AQjoFA;EAoLI,aAAa;EACb,WAAW;ARi9Ef;;AQtoFA;EAuLI,6BAA6B;EAC7B,oBAAoB;ARm9ExB;;AQ3oFA;EPpCE,kBAAkB;EAKhB,2BAAiC;EACjC,0BAAgC;EO0N9B,6BAA6B;ARs9EnC;;AQlpFA;EA8LI,4BN/N0B;EMgO1B,qBNlO0B;EMmO1B,cNrO0B;EMsO1B,gBAAgB;EAChB,oBAAoB;ARw9ExB;;AQ1pFA;EAoMI,uBN3KqB;EM4KrB,iBAAiB;EACjB,kBAAkB;AR09EtB;;AQx9EA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;AR29E7B;;AQ/9EA;EAMI,qBAAqB;AR69EzB;;AQn+EA;EAQM,oBAAoB;AR+9E1B;;AQv+EA;EAUI,sBAAsB;ARi+E1B;;AQ3+EA;EAYI,mBAAmB;ARm+EvB;;AQ/+EA;EAjNE,kBN+BgB;EM9BhB,kBNAc;AFosFhB;;AQp/EA;EA5ME,kBNNc;AF0sFhB;;AQx/EA;EA1ME,iBNTa;AF+sFf;;AQ5/EA;EA0BQ,4BAA4B;EAC5B,yBAAyB;ARs+EjC;;AQjgFA;EA6BQ,6BAA6B;EAC7B,0BAA0B;EAC1B,kBAAkB;ARw+E1B;;AQvgFA;EAiCQ,eAAe;AR0+EvB;;AQ3gFA;EAoCQ,UAAU;AR2+ElB;;AQ/gFA;EA0CQ,UAAU;ARy+ElB;;AQnhFA;EA4CU,UAAU;AR2+EpB;;AQvhFA;EA8CQ,YAAY;EACZ,cAAc;AR6+EtB;;AQ5hFA;EAiDI,uBAAuB;AR++E3B;;AQhiFA;EAoDQ,oBAAoB;EACpB,qBAAqB;ARg/E7B;;AQriFA;EAuDI,yBAAyB;ARk/E7B;;AQziFA;EA0DQ,oBAAoB;EACpB,qBAAqB;ARm/E7B;;AUjyFA;EACE,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,WAAW;AVoyFb;;ACzsFE;ES/FF;IAMI,gBAAuC;EVuyFzC;EU7yFF;IAQM,iBR0CI;IQzCJ,kBRyCI;IQxCJ,eAAe;EVwyFnB;AACF;;AC1sFI;ESzGJ;IAaM,iBAA0C;EV2yF9C;AACF;;ACjsFI;ESxHJ;IAgBM,iBAAsC;EV8yF1C;AACF;;ACjtFI;ES9GJ;IAkBI,iBAA0C;EVkzF5C;AACF;;ACxsFI;ES7HJ;IAoBI,iBAAsC;EVszFxC;AACF;;AW1zFA;EAII,kBAAkB;AX0zFtB;;AW9zFA;;;;;;;EAcM,kBAAkB;AX0zFxB;;AWx0FA;;;;;;EAqBI,cTlC0B;ESmC1B,gBTCiB;ESAjB,kBAxC+B;AXo2FnC;;AWn1FA;EAyBI,cAAc;EACd,oBAAoB;AX8zFxB;;AWx1FA;EA4BM,eAAe;AXg0FrB;;AW51FA;EA8BI,iBAAiB;EACjB,uBAAuB;AXk0F3B;;AWj2FA;EAiCM,oBAAoB;AXo0F1B;;AWr2FA;EAmCI,gBAAgB;EAChB,uBAAuB;AXs0F3B;;AW12FA;EAsCM,oBAAoB;AXw0F1B;;AW92FA;EAwCI,iBAAiB;EACjB,oBAAoB;AX00FxB;;AWn3FA;EA2CI,kBAAkB;EAClB,uBAAuB;AX40F3B;;AWx3FA;EA8CI,cAAc;EACd,kBAAkB;AX80FtB;;AW73FA;EAiDI,4BTxD0B;ESyD1B,8BT3D0B;ES4D1B,qBAhEqC;AXg5FzC;;AWn4FA;EAqDI,4BAA4B;EAC5B,gBAAgB;EAChB,eAAe;AXk1FnB;;AWz4FA;EAyDM,wBAAwB;AXo1F9B;;AW74FA;EA2DQ,4BAA4B;AXs1FpC;;AWj5FA;EA6DQ,4BAA4B;AXw1FpC;;AWr5FA;EA+DQ,4BAA4B;AX01FpC;;AWz5FA;EAiEQ,4BAA4B;AX41FpC;;AW75FA;EAmEI,wBAAwB;EACxB,gBAAgB;EAChB,eAAe;AX81FnB;;AWn6FA;EAuEM,uBAAuB;EACvB,iBAAiB;AXg2FvB;;AWx6FA;EA0EQ,uBAAuB;AXk2F/B;;AW56FA;EA4EI,gBAAgB;AXo2FpB;;AWh7FA;EA8EI,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;AXs2FtB;;AWt7FA;EAkFM,eAAe;AXw2FrB;;AW17FA;EAoFM,kBAAkB;AX02FxB;;AW97FA;EAsFM,qBAAqB;AX42F3B;;AWl8FA;EAwFM,kBAAkB;AX82FxB;;AWt8FA;EV2CE,iCAAiC;EUgD/B,gBAAgB;EAChB,qBAvG8B;EAwG9B,gBAAgB;EAChB,iBAAiB;AXg3FrB;;AW98FA;;EAiGI,cAAc;AXk3FlB;;AWn9FA;EAmGI,WAAW;AXo3Ff;;AWv9FA;;EAsGM,yBT/GwB;ESgHxB,qBA/GmC;EAgHnC,qBA/GmC;EAgHnC,mBAAmB;AXs3FzB;;AW/9FA;EA2GM,cTxHwB;AFg/F9B;;AWn+FA;EA6GQ,gBAAgB;AX03FxB;;AWv+FA;;EAiHQ,qBAtHsC;EAuHtC,cT/HsB;AF0/F9B;;AW7+FA;;EAsHQ,qBAzHsC;EA0HtC,cTpIsB;AFggG9B;;AWn/FA;;EA6HY,sBAAsB;AX23FlC;;AWx/FA;EAgIM,aAAa;AX43FnB;;AW5/FA;EAmII,kBTjHY;AF8+FhB;;AWhgGA;EAqII,kBTrHY;AFo/FhB;;AWpgGA;EAuII,iBTxHW;AFy/Ff;;AYthGA;EACE,mBAAmB;EACnB,oBAAoB;EACpB,uBAAuB;EACvB,cATsB;EAUtB,aAVsB;AZmiGxB;;AY9hGA;EAQI,YAZwB;EAaxB,WAbwB;AZuiG5B;;AYniGA;EAWI,YAdyB;EAezB,WAfyB;AZ2iG7B;;AYxiGA;EAcI,YAhBwB;EAiBxB,WAjBwB;AZ+iG5B;;AahjGA;EACE,cAAc;EACd,kBAAkB;AbmjGpB;;AarjGA;EAII,cAAc;EACd,YAAY;EACZ,WAAW;AbqjGf;;Aa3jGA;EAQM,uBX4DmB;AF2/FzB;;Aa/jGA;;;;;;;;;;;;;;;;;EA6BM,YAAY;EACZ,WAAW;AbsjGjB;;AaplGA;EAiCI,iBAAiB;AbujGrB;;AaxlGA;EAmCI,gBAAgB;AbyjGpB;;Aa5lGA;EAqCI,gBAAgB;Ab2jGpB;;AahmGA;EAuCI,qBAAqB;Ab6jGzB;;AapmGA;EAyCI,gBAAgB;Ab+jGpB;;AaxmGA;EA2CI,mBAAmB;AbikGvB;;Aa5mGA;EA6CI,gBAAgB;AbmkGpB;;AahnGA;EA+CI,qBAAqB;AbqkGzB;;AapnGA;EAiDI,iBAAiB;AbukGrB;;AaxnGA;EAmDI,sBAAsB;AbykG1B;;Aa5nGA;EAqDI,iBAAiB;Ab2kGrB;;AahoGA;EAuDI,sBAAsB;Ab6kG1B;;AapoGA;EAyDI,sBAAsB;Ab+kG1B;;AaxoGA;EA2DI,iBAAiB;AbilGrB;;Aa5oGA;EA6DI,iBAAiB;AbmlGrB;;AahpGA;EAiEM,YAAwB;EACxB,WAAuB;AbmlG7B;;AarpGA;EAiEM,YAAwB;EACxB,WAAuB;AbwlG7B;;Aa1pGA;EAiEM,YAAwB;EACxB,WAAuB;Ab6lG7B;;Aa/pGA;EAiEM,YAAwB;EACxB,WAAuB;AbkmG7B;;AapqGA;EAiEM,YAAwB;EACxB,WAAuB;AbumG7B;;AazqGA;EAiEM,YAAwB;EACxB,WAAuB;Ab4mG7B;;Aa9qGA;EAiEM,aAAwB;EACxB,YAAuB;AbinG7B;;AcjrGA;EAEE,4BZM4B;EYL5B,kBZ6DU;EY5DV,sCANkD;EAOlD,kBAAkB;AdmrGpB;;AcxrGA;EAOI,mBAAmB;EACnB,0BAA0B;AdqrG9B;;Ac7rGA;EAUI,mBAAmB;AdurGvB;;AcjsGA;;EAaI,iBZH2B;AF4rG/B;;ActsGA;EAeI,uBAAuB;Ad2rG3B;;Ac1sGA;EAiBI,kBAAkB;EAClB,aAAa;EACb,WAAW;Ad6rGf;;AchtGA;;;EAuBI,mBAAmB;Ad+rGvB;;ActtGA;EA6BM,uBZnByB;EYoBzB,cZhCuB;AF6tG7B;;Ac3tGA;EA6BM,yBZ/BuB;EYgCvB,YZpByB;AFstG/B;;AchuGA;EA6BM,4BZrBwB;EYsBxB,cZ5BwB;AFmuG9B;;AcruGA;EA6BM,yBZ3BwB;EY4BxB,iBZtBwB;AFkuG9B;;Ac1uGA;EA6BM,yBZd4B;EYe5B,WL2BU;ATsrGhB;;Ac/uGA;EA6BM,yBZZ4B;EYa5B,WL2BU;AT2rGhB;;AcpvGA;EA6BM,yBZb4B;EYc5B,WL2BU;ATgsGhB;;AczvGA;EA6BM,yBZf4B;EYgB5B,WL2BU;ATqsGhB;;Ac9vGA;EA6BM,yBZhB4B;EYiB5B,yBLyBe;AT4sGrB;;AcnwGA;EA6BM,yBZV4B;EYW5B,WL2BU;AT+sGhB;;AetwGA;EAEE,qBAAqB;EACrB,wBAAwB;EACxB,YAAY;EACZ,uBb2DuB;Ea1DvB,cAAc;EACd,YbuBW;EatBX,gBAAgB;EAChB,UAAU;EACV,WAAW;AfwwGb;;AelxGA;EAYI,yBbR0B;AFkxG9B;;AetxGA;EAcI,yBbb0B;AFyxG9B;;Ae1xGA;EAgBI,yBbf0B;AF6xG9B;;Ae9xGA;EAkBI,yBbjB0B;EakB1B,YAAY;AfgxGhB;;AenyGA;EAyBQ,uBbjBuB;AF+xG/B;;AevyGA;EA2BQ,uBbnBuB;AFmyG/B;;Ae3yGA;EA6BQ,uBbrBuB;AFuyG/B;;Ae/yGA;EA+BQ,mEAA2F;AfoxGnG;;AenzGA;EAyBQ,yBb7BqB;AF2zG7B;;AevzGA;EA2BQ,yBb/BqB;AF+zG7B;;Ae3zGA;EA6BQ,yBbjCqB;AFm0G7B;;Ae/zGA;EA+BQ,qEAA2F;AfoyGnG;;Aen0GA;EAyBQ,4BbnBsB;AFi0G9B;;Aev0GA;EA2BQ,4BbrBsB;AFq0G9B;;Ae30GA;EA6BQ,4BbvBsB;AFy0G9B;;Ae/0GA;EA+BQ,wEAA2F;AfozGnG;;Aen1GA;EAyBQ,yBbzBsB;AFu1G9B;;Aev1GA;EA2BQ,yBb3BsB;AF21G9B;;Ae31GA;EA6BQ,yBb7BsB;AF+1G9B;;Ae/1GA;EA+BQ,qEAA2F;Afo0GnG;;Aen2GA;EAyBQ,yBbZ0B;AF01GlC;;Aev2GA;EA2BQ,yBbd0B;AF81GlC;;Ae32GA;EA6BQ,yBbhB0B;AFk2GlC;;Ae/2GA;EA+BQ,qEAA2F;Afo1GnG;;Aen3GA;EAyBQ,yBbV0B;AFw2GlC;;Aev3GA;EA2BQ,yBbZ0B;AF42GlC;;Ae33GA;EA6BQ,yBbd0B;AFg3GlC;;Ae/3GA;EA+BQ,qEAA2F;Afo2GnG;;Aen4GA;EAyBQ,yBbX0B;AFy3GlC;;Aev4GA;EA2BQ,yBbb0B;AF63GlC;;Ae34GA;EA6BQ,yBbf0B;AFi4GlC;;Ae/4GA;EA+BQ,qEAA2F;Afo3GnG;;Aen5GA;EAyBQ,yBbb0B;AF24GlC;;Aev5GA;EA2BQ,yBbf0B;AF+4GlC;;Ae35GA;EA6BQ,yBbjB0B;AFm5GlC;;Ae/5GA;EA+BQ,qEAA2F;Afo4GnG;;Aen6GA;EAyBQ,yBbd0B;AF45GlC;;Aev6GA;EA2BQ,yBbhB0B;AFg6GlC;;Ae36GA;EA6BQ,yBblB0B;AFo6GlC;;Ae/6GA;EA+BQ,qEAA2F;Afo5GnG;;Aen7GA;EAyBQ,yBbR0B;AFs6GlC;;Aev7GA;EA2BQ,yBbV0B;AF06GlC;;Ae37GA;EA6BQ,yBbZ0B;AF86GlC;;Ae/7GA;EA+BQ,qEAA2F;Afo6GnG;;Aen8GA;EAkCI,gCApCkC;UAoClC,wBApCkC;EAqClC,2CAAmC;UAAnC,mCAAmC;EACnC,yCAAiC;UAAjC,iCAAiC;EACjC,yCAAiC;UAAjC,iCAAiC;EACjC,yBblC0B;EamC1B,qEAA0F;EAC1F,6BAA6B;EAC7B,4BAA4B;EAC5B,0BAA0B;Afq6G9B;;Ae/8GA;EA4CM,6BAA6B;Afu6GnC;;Aen9GA;EA8CM,6BAA6B;Afy6GnC;;Aev9GA;EAkDI,ebnBY;AF47GhB;;Ae39GA;EAoDI,ebvBY;AFk8GhB;;Ae/9GA;EAsDI,cb1BW;AFu8Gf;;Ae36GA;EACE;IACE,2BAA2B;Ef86G7B;Ee76GA;IACE,4BAA4B;Ef+6G9B;AACF;;Aep7GA;EACE;IACE,2BAA2B;Ef86G7B;Ee76GA;IACE,4BAA4B;Ef+6G9B;AACF;;AgBz9GA;EAEE,uBdb6B;Ecc7B,cdtB4B;AFi/G9B;;AgB99GA;;EAMI,yBdrB0B;EcsB1B,qBA5B6B;EA6B7B,qBA5B6B;EA6B7B,mBAAmB;AhB69GvB;;AgBt+GA;;EAeQ,uBd1BuB;Ec2BvB,mBd3BuB;Ec4BvB,cdxCqB;AFogH7B;;AgB7+GA;;EAeQ,yBdtCqB;EcuCrB,qBdvCqB;EcwCrB,Yd5BuB;AF+/G/B;;AgBp/GA;;EAeQ,4Bd5BsB;Ec6BtB,wBd7BsB;Ec8BtB,cdpCsB;AF8gH9B;;AgB3/GA;;EAeQ,yBdlCsB;EcmCtB,qBdnCsB;EcoCtB,iBd9BsB;AF+gH9B;;AgBlgHA;;EAeQ,yBdrB0B;EcsB1B,qBdtB0B;EcuB1B,WPmBQ;ATq+GhB;;AgBzgHA;;EAeQ,yBdnB0B;EcoB1B,qBdpB0B;EcqB1B,WPmBQ;AT4+GhB;;AgBhhHA;;EAeQ,yBdpB0B;EcqB1B,qBdrB0B;EcsB1B,WPmBQ;ATm/GhB;;AgBvhHA;;EAeQ,yBdtB0B;EcuB1B,qBdvB0B;EcwB1B,WPmBQ;AT0/GhB;;AgB9hHA;;EAeQ,yBdvB0B;EcwB1B,qBdxB0B;EcyB1B,yBPiBa;ATmgHrB;;AgBriHA;;EAeQ,yBdjB0B;EckB1B,qBdlB0B;EcmB1B,WPmBQ;ATwgHhB;;AgB5iHA;;EAoBM,mBAAmB;EACnB,SAAS;AhB6hHf;;AgBljHA;;EAuBM,yBd7B4B;Ec8B5B,WPYU;ATohHhB;;AgBxjHA;;;;EA2BQ,mBAAmB;AhBoiH3B;;AgB/jHA;EA6BI,cdhD0B;AFslH9B;;AgBnkHA;EA+BM,gBAAgB;AhBwiHtB;;AgBvkHA;EAkCM,yBdxC4B;EcyC5B,WPCU;ATwiHhB;;AgB5kHA;;EAsCQ,mBAAmB;AhB2iH3B;;AgBjlHA;;EAyCQ,kBPLQ;EOMR,mBAAmB;AhB6iH3B;;AgBvlHA;EA4CI,6BAxDqC;AhBumHzC;;AgB3lHA;;EA+CM,qBAhEgC;EAiEhC,cdnEwB;AFonH9B;;AgBjmHA;EAkDI,6BA5DqC;AhB+mHzC;;AgBrmHA;;EAqDM,qBApEgC;EAqEhC,cdzEwB;AF8nH9B;;AgB3mHA;EAwDI,6BAnEqC;AhB0nHzC;;AgB/mHA;;EA6DU,sBAAsB;AhBujHhC;;AgBpnHA;;EAkEM,iBAAiB;AhBujHvB;;AgBznHA;;EAuEU,wBAAwB;AhBujHlC;;AgB9nHA;EAyEI,WAAW;AhByjHf;;AgBloHA;EA8EU,yBd1FoB;AFkpH9B;;AgBtoHA;EAmFY,yBd/FkB;AFspH9B;;AgB1oHA;EAqFc,4BdlGgB;AF2pH9B;;AgB9oHA;;EAyFM,qBAAqB;AhB0jH3B;;AgBnpHA;EA8FU,yBd1GoB;AFmqH9B;;AgBvjHA;Ef3DE,iCAAiC;Ee8DjC,cAAc;EACd,kBAAkB;EAClB,eAAe;AhByjHjB;;AiBlrHA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;AjBqrH7B;;AiBzrHA;EAMI,qBAAqB;AjBurHzB;;AiB7rHA;EAQM,oBAAoB;AjByrH1B;;AiBjsHA;EAUI,sBAAsB;AjB2rH1B;;AiBrsHA;EAYI,mBAAmB;AjB6rHvB;;AiBzsHA;EAgBM,efeO;AF8qHb;;AiB7sHA;EAmBM,kBfWU;AFmrHhB;;AiBjtHA;EAqBI,uBAAuB;AjBgsH3B;;AiBrtHA;EAuBM,qBAAqB;EACrB,oBAAoB;AjBksH1B;;AiB1tHA;EA0BI,yBAAyB;AjBosH7B;;AiB9tHA;EA6BQ,mBAAmB;AjBqsH3B;;AiBluHA;EA+BQ,eAAe;AjBusHvB;;AiBtuHA;EAkCM,eAAe;AjBwsHrB;;AiB1uHA;EAoCQ,cAAc;EACd,4BAA4B;EAC5B,yBAAyB;AjB0sHjC;;AiBhvHA;EAwCQ,6BAA6B;EAC7B,0BAA0B;AjB4sHlC;;AiB1sHA;EACE,mBAAmB;EACnB,4BftC4B;EeuC5B,kBfiBU;EehBV,cf7C4B;Ee8C5B,oBAAoB;EACpB,kBfjBc;EekBd,WAAW;EACX,uBAAuB;EACvB,gBAAgB;EAChB,oBAAoB;EACpB,qBAAqB;EACrB,mBAAmB;AjB6sHrB;;AiBztHA;EAcI,oBAAoB;EACpB,uBAAuB;AjB+sH3B;;AiB9tHA;EAqBM,uBfvDyB;EewDzB,cfpEuB;AFixH7B;;AiBnuHA;EAqBM,yBfnEuB;EeoEvB,YfxDyB;AF0wH/B;;AiBxuHA;EAqBM,4BfzDwB;Ee0DxB,cfhEwB;AFuxH9B;;AiB7uHA;EAqBM,yBf/DwB;EegExB,iBf1DwB;AFsxH9B;;AiBlvHA;EAqBM,yBflD4B;EemD5B,WRTU;AT0uHhB;;AiBvvHA;EAqBM,yBfhD4B;EeiD5B,WRTU;AT+uHhB;;AiB5vHA;EAqBM,yBfjD4B;EekD5B,WRTU;ATovHhB;;AiBjwHA;EAqBM,yBfnD4B;EeoD5B,WRTU;ATyvHhB;;AiBtwHA;EAqBM,yBfpD4B;EeqD5B,yBRXe;ATgwHrB;;AiB3wHA;EAqBM,yBf9C4B;Ee+C5B,WRTU;ATmwHhB;;AiBhxHA;EAyBI,kBfpCY;AF+xHhB;;AiBpxHA;EA2BI,efvCS;AFoyHb;;AiBxxHA;EA6BI,kBf1CY;AFyyHhB;;AiB5xHA;EAgCM,qBAAqB;EACrB,sBAAsB;AjBgwH5B;;AiBjyHA;EAmCM,qBAAqB;EACrB,sBAAsB;AjBkwH5B;;AiBtyHA;EAsCM,qBAAqB;EACrB,sBAAsB;AjBowH5B;;AiB3yHA;EA0CI,gBAvFmB;EAwFnB,UAAU;EACV,kBAAkB;EAClB,UAAU;AjBqwHd;;AiBlzHA;EAgDM,8BAA8B;EAC9B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,kEAA0D;UAA1D,0DAA0D;EAC1D,uCAA+B;UAA/B,+BAA+B;AjBswHrC;;AiB7zHA;EAyDM,WAAW;EACX,UAAU;AjBwwHhB;;AiBl0HA;EA4DM,WAAW;EACX,UAAU;AjB0wHhB;;AiBv0HA;EAgEM,yBAAmD;AjB2wHzD;;AiB30HA;EAkEM,yBAAoD;AjB6wH1D;;AiB/0HA;EAoEI,uBf9CqB;AF6zHzB;;AiB7wHA;EAEI,0BAA0B;AjB+wH9B;;AkBp3HA;;EAGE,sBAAsB;AlBs3HxB;;AkBz3HA;;;;EAMI,oBAAoB;AlB03HxB;;AkBh4HA;;EAQI,iBApBmB;AlBi5HvB;;AkBr4HA;;EAUI,iBArBmB;AlBq5HvB;;AkB14HA;;EAYI,sBAAsB;AlBm4H1B;;AkBj4HA;EACE,chB5B4B;EgB+B5B,ehBJW;EgBKX,gBhBImB;EgBHnB,kBAnCuB;AlBq6HzB;;AkBx4HA;EAQI,cApCwB;EAqCxB,oBApCyB;AlBw6H7B;;AkB74HA;EAWI,oBAAoB;AlBs4HxB;;AkBj5HA;EAaI,oBA7B+B;AlBq6HnC;;AkBr5HA;EAkBM,ehBpBO;AF25Hb;;AkBz5HA;EAkBM,iBhBnBS;AF85Hf;;AkB75HA;EAkBM,ehBlBO;AFi6Hb;;AkBj6HA;EAkBM,iBhBjBS;AFo6Hf;;AkBr6HA;EAkBM,kBhBhBU;AFu6HhB;;AkBz6HA;EAkBM,ehBfO;AF06Hb;;AkB76HA;EAkBM,kBhBdU;AF66HhB;;AkB75HA;EACE,chB/C4B;EgBkD5B,kBhBtBc;EgBuBd,gBhBlBiB;EgBmBjB,iBA7CyB;AlB28H3B;;AkBp6HA;EAQI,chBvD0B;EgBwD1B,gBhBpBiB;AFo7HrB;;AkBz6HA;EAWI,oBA/C+B;AlBi9HnC;;AkB76HA;EAgBM,ehBtCO;AFu8Hb;;AkBj7HA;EAgBM,iBhBrCS;AF08Hf;;AkBr7HA;EAgBM,ehBpCO;AF68Hb;;AkBz7HA;EAgBM,iBhBnCS;AFg9Hf;;AkB77HA;EAgBM,kBhBlCU;AFm9HhB;;AkBj8HA;EAgBM,ehBjCO;AFs9Hb;;AkBr8HA;EAgBM,kBhBhCU;AFy9HhB;;AmBx/HA;EACE,cAAc;EACd,eAAe;EACf,mBAAmB;EACnB,kBAAkB;EAClB,yBAAyB;AnB2/H3B;;AmBz/HA;EAEE,gBjByBiB;EiBxBjB,eAAe;EACf,gBAAgB;EAChB,UAAU;AnB2/HZ;;AmBhgIA;EAOI,cAAc;EACd,eAAe;AnB6/HnB;;AmBx/HA;EACE,mBAAmB;EACnB,4BjBhB4B;EiBiB5B,uBjByCuB;EiBxCvB,oBAAoB;EACpB,kBjBIc;EiBHd,WAAW;EACX,uBAAuB;EACvB,oBAAoB;EACpB,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;EAClB,mBAAmB;AnB2/HrB;;AoB5+HA;EAxBE,uBlBf6B;EkBgB7B,qBlBpB4B;EkBqB5B,kBlBqCU;EkBpCV,clB1B4B;AFkiI9B;;ACr+HI;EmBjCA,4BlB5B0B;AFsiI9B;;ACz+HI;EmBjCA,4BlB5B0B;AF0iI9B;;AC7+HI;EmBjCA,4BlB5B0B;AF8iI9B;;ACj/HI;EmBjCA,4BlB5B0B;AFkjI9B;;AoBrhIE;EAEE,qBlB5B0B;AFmjI9B;;AoBthIE;EAIE,qBlBrB8B;EkBsB9B,kDlBtB8B;AF4iIlC;;AoBrhIE;;;;;EAEE,4BlBlC0B;EkBmC1B,wBlBnC0B;EkBoC1B,gBAAgB;EAChB,clBzC0B;AFokI9B;;ACzgII;;;;;EmBhBE,+BlB3CwB;AF4kI9B;;ACjhII;;;;;EmBhBE,+BlB3CwB;AFolI9B;;ACzhII;;;;;EmBhBE,+BlB3CwB;AF4lI9B;;ACjiII;;;;;EmBhBE,+BlB3CwB;AFomI9B;;AqB5mIA;EAEE,iDnBA2B;EmBC3B,eAAe;EACf,WAAW;ArB8mIb;;AqB7mIE;EACE,gBAAgB;ArBgnIpB;;AqB5mII;EACE,mBnBGyB;AF4mI/B;;AqBhnIK;EAMG,mDnBFuB;AFgnI/B;;AqBpnII;EACE,qBnBTuB;AFgoI7B;;AqBxnIK;EAMG,gDnBdqB;AFooI7B;;AqB5nII;EACE,wBnBCwB;AF8nI9B;;AqBhoIK;EAMG,mDnBJsB;AFkoI9B;;AqBpoII;EACE,qBnBLwB;AF4oI9B;;AqBxoIK;EAMG,gDnBVsB;AFgpI9B;;AqB5oII;EACE,qBnBQ4B;AFuoIlC;;AqBhpIK;EAMG,iDnBG0B;AF2oIlC;;AqBppII;EACE,qBnBU4B;AF6oIlC;;AqBxpIK;EAMG,kDnBK0B;AFipIlC;;AqB5pII;EACE,qBnBS4B;AFspIlC;;AqBhqIK;EAMG,kDnBI0B;AF0pIlC;;AqBpqII;EACE,qBnBO4B;AFgqIlC;;AqBxqIK;EAMG,iDnBE0B;AFoqIlC;;AqB5qII;EACE,qBnBM4B;AFyqIlC;;AqBhrIK;EAMG,kDnBC0B;AF6qIlC;;AqBprII;EACE,qBnBY4B;AF2qIlC;;AqBxrIK;EAMG,iDnBO0B;AF+qIlC;;AqBprIE;ElB0BA,kBDuBgB;ECtBhB,kBDRc;AFsqIhB;;AqBvrIE;ElB2BA,kBDZc;AF4qIhB;;AqBzrIE;ElB2BA,iBDfa;AFirIf;;AqB1rIE;EACE,cAAc;EACd,WAAW;ArB6rIf;;AqB5rIE;EACE,eAAe;EACf,WAAW;ArB+rIf;;AqB7rIA;EAGI,uBnBmCqB;EmBlCrB,iBAAiB;EACjB,kBAAkB;ArB8rItB;;AqBnsIA;EAOI,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;ArBgsIpB;;AqB9rIA;EAEE,cAAc;EACd,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,gBAAgB;ArBgsIlB;;AqBtsIA;EAQI,iBAAiB;EACjB,iBAAiB;ArBksIrB;;AqB3sIA;EAWI,eAAe;ArBosInB;;AqB/sIA;EAcI,YAAY;ArBqsIhB;;AsBhwIA;EACE,eAAe;EACf,qBAAqB;EACrB,iBAAiB;EACjB,kBAAkB;AtBmwIpB;;AsBlwIE;EACE,eAAe;AtBqwInB;;AsBpwIE;EACE,cpBF0B;AFywI9B;;AsBtwIE;;;EAEE,cpBH0B;EoBI1B,mBAAmB;AtB0wIvB;;AsBrwIA;EAGI,kBAAkB;AtBswItB;;AuB1xIA;EACE,qBAAqB;EACrB,eAAe;EACf,kBAAkB;EAClB,mBAAmB;AvB6xIrB;;AuBjyIA;EAMI,cpBDmB;AHgyIvB;;AuBryIA;EAUM,qBrBW4B;EqBV5B,cAAc;EACd,UAAU;AvB+xIhB;;AuB3yIA;EAeM,uBrBuDmB;EqBtDnB,iBAAiB;AvBgyIvB;;AuBhzIA;EAmBI,eAAe;EACf,cAAc;EACd,cAAc;EACd,eAAe;EACf,aAAa;AvBiyIjB;;AuBxzIA;EAyBM,aAAa;AvBmyInB;;AuB5zIA;;EA4BM,wBrBhBwB;AFqzI9B;;AuBj0IA;EA8BM,oBAAoB;AvBuyI1B;;AuBr0IA;EAgCM,YAAY;EACZ,UAAU;AvByyIhB;;AuB10IA;EAmCQ,kBAAkB;AvB2yI1B;;AuB90IA;EAuCM,qBrBjCwB;AF40I9B;;AuBl1IA;EA6CQ,mBrB/BuB;AFw0I/B;;AuBt1IA;EA+CQ,mBrBjCuB;AF40I/B;;AuB11IA;EAkDU,qBAAgC;AvB4yI1C;;AuB91IA;EAuDU,mDrBzCqB;AFo1I/B;;AuBl2IA;EA6CQ,qBrB3CqB;AFo2I7B;;AuBt2IA;EA+CQ,qBrB7CqB;AFw2I7B;;AuB12IA;EAkDU,mBAAgC;AvB4zI1C;;AuB92IA;EAuDU,gDrBrDmB;AFg3I7B;;AuBl3IA;EA6CQ,wBrBjCsB;AF02I9B;;AuBt3IA;EA+CQ,wBrBnCsB;AF82I9B;;AuB13IA;EAkDU,qBAAgC;AvB40I1C;;AuB93IA;EAuDU,mDrB3CoB;AFs3I9B;;AuBl4IA;EA6CQ,qBrBvCsB;AFg4I9B;;AuBt4IA;EA+CQ,qBrBzCsB;AFo4I9B;;AuB14IA;EAkDU,qBAAgC;AvB41I1C;;AuB94IA;EAuDU,gDrBjDoB;AF44I9B;;AuBl5IA;EA6CQ,qBrB1B0B;AFm4IlC;;AuBt5IA;EA+CQ,qBrB5B0B;AFu4IlC;;AuB15IA;EAkDU,qBAAgC;AvB42I1C;;AuB95IA;EAuDU,iDrBpCwB;AF+4IlC;;AuBl6IA;EA6CQ,qBrBxB0B;AFi5IlC;;AuBt6IA;EA+CQ,qBrB1B0B;AFq5IlC;;AuB16IA;EAkDU,qBAAgC;AvB43I1C;;AuB96IA;EAuDU,kDrBlCwB;AF65IlC;;AuBl7IA;EA6CQ,qBrBzB0B;AFk6IlC;;AuBt7IA;EA+CQ,qBrB3B0B;AFs6IlC;;AuB17IA;EAkDU,qBAAgC;AvB44I1C;;AuB97IA;EAuDU,kDrBnCwB;AF86IlC;;AuBl8IA;EA6CQ,qBrB3B0B;AFo7IlC;;AuBt8IA;EA+CQ,qBrB7B0B;AFw7IlC;;AuB18IA;EAkDU,qBAAgC;AvB45I1C;;AuB98IA;EAuDU,iDrBrCwB;AFg8IlC;;AuBl9IA;EA6CQ,qBrB5B0B;AFq8IlC;;AuBt9IA;EA+CQ,qBrB9B0B;AFy8IlC;;AuB19IA;EAkDU,qBAAgC;AvB46I1C;;AuB99IA;EAuDU,kDrBtCwB;AFi9IlC;;AuBl+IA;EA6CQ,qBrBtB0B;AF+8IlC;;AuBt+IA;EA+CQ,qBrBxB0B;AFm9IlC;;AuB1+IA;EAkDU,qBAAgC;AvB47I1C;;AuB9+IA;EAuDU,iDrBhCwB;AF29IlC;;AuBl/IA;EpB4CE,kBDuBgB;ECtBhB,kBDRc;AFk9IhB;;AuBv/IA;EpB+CE,kBDZc;AFw9IhB;;AuB3/IA;EpBiDE,iBDfa;AF69If;;AuB//IA;EAkEM,qBrB1DwB;AF2/I9B;;AuBngJA;EAoEI,WAAW;AvBm8If;;AuBvgJA;EAsEM,WAAW;AvBq8IjB;;AuB3gJA;EA0EM,aAAa;EACb,kBAAkB;EAClB,cAAc;EACd,YAAY;EACZ,uBAAe;UAAf,eAAe;AvBq8IrB;;AuBnhJA;EAgFM,kBrB3CU;AFk/IhB;;AuBvhJA;EAkFM,kBrB/CU;AFw/IhB;;AuB3hJA;EAoFM,iBrBlDS;AF6/If;;AwBlhJA;EAEE,oBAAoB;EACpB,aAAa;EACb,2BAA2B;EAC3B,kBAAkB;AxBohJpB;;AwBzhJA;EAYQ,uBtBXuB;EsBYvB,yBAAyB;EACzB,ctBzBqB;AF0iJ7B;;AwB/hJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,ctB/BmB;AFgjJ7B;;AwBriJA;EAwBU,yBAAyB;EACzB,+CtBxBqB;EsByBrB,ctBrCmB;AFsjJ7B;;AwB3iJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,ctB3CmB;AF4jJ7B;;AwBjjJA;EAYQ,yBtBvBqB;EsBwBrB,yBAAyB;EACzB,YtBbuB;AFsjJ/B;;AwBvjJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,YtBnBqB;AF4jJ/B;;AwB7jJA;EAwBU,yBAAyB;EACzB,4CtBpCmB;EsBqCnB,YtBzBqB;AFkkJ/B;;AwBnkJA;EA8BU,uBAAoC;EACpC,yBAAyB;EACzB,YtB/BqB;AFwkJ/B;;AwBzkJA;EAYQ,4BtBbsB;EsBctB,yBAAyB;EACzB,ctBrBsB;AFslJ9B;;AwB/kJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,ctB3BoB;AF4lJ9B;;AwBrlJA;EAwBU,yBAAyB;EACzB,+CtB1BoB;EsB2BpB,ctBjCoB;AFkmJ9B;;AwB3lJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,ctBvCoB;AFwmJ9B;;AwBjmJA;EAYQ,yBtBnBsB;EsBoBtB,yBAAyB;EACzB,iBtBfsB;AFwmJ9B;;AwBvmJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,iBtBrBoB;AF8mJ9B;;AwB7mJA;EAwBU,yBAAyB;EACzB,4CtBhCoB;EsBiCpB,iBtB3BoB;AFonJ9B;;AwBnnJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,iBtBjCoB;AF0nJ9B;;AwBznJA;EAYQ,yBtBN0B;EsBO1B,yBAAyB;EACzB,WfkCQ;AT+kJhB;;AwB/nJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,Wf4BM;ATqlJhB;;AwBroJA;EAwBU,yBAAyB;EACzB,6CtBnBwB;EsBoBxB,WfsBM;AT2lJhB;;AwB3oJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,WfgBM;ATimJhB;;AwBjpJA;EAYQ,yBtBJ0B;EsBK1B,yBAAyB;EACzB,WfkCQ;ATumJhB;;AwBvpJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,Wf4BM;AT6mJhB;;AwB7pJA;EAwBU,yBAAyB;EACzB,8CtBjBwB;EsBkBxB,WfsBM;ATmnJhB;;AwBnqJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,WfgBM;ATynJhB;;AwBzqJA;EAYQ,yBtBL0B;EsBM1B,yBAAyB;EACzB,WfkCQ;AT+nJhB;;AwB/qJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,Wf4BM;ATqoJhB;;AwBrrJA;EAwBU,yBAAyB;EACzB,8CtBlBwB;EsBmBxB,WfsBM;AT2oJhB;;AwB3rJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,WfgBM;ATipJhB;;AwBjsJA;EAYQ,yBtBP0B;EsBQ1B,yBAAyB;EACzB,WfkCQ;ATupJhB;;AwBvsJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,Wf4BM;AT6pJhB;;AwB7sJA;EAwBU,yBAAyB;EACzB,6CtBpBwB;EsBqBxB,WfsBM;ATmqJhB;;AwBntJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,WfgBM;ATyqJhB;;AwBztJA;EAYQ,yBtBR0B;EsBS1B,yBAAyB;EACzB,yBfgCa;ATirJrB;;AwB/tJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,yBf0BW;ATurJrB;;AwBruJA;EAwBU,yBAAyB;EACzB,8CtBrBwB;EsBsBxB,yBfoBW;AT6rJrB;;AwB3uJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,yBfcW;ATmsJrB;;AwBjvJA;EAYQ,yBtBF0B;EsBG1B,yBAAyB;EACzB,WfkCQ;ATusJhB;;AwBvvJA;EAkBU,yBAAsC;EACtC,yBAAyB;EACzB,Wf4BM;AT6sJhB;;AwB7vJA;EAwBU,yBAAyB;EACzB,6CtBfwB;EsBgBxB,WfsBM;ATmtJhB;;AwBnwJA;EA8BU,yBAAoC;EACpC,yBAAyB;EACzB,WfgBM;ATytJhB;;AwBzwJA;EAmCI,kBtBXY;AFqvJhB;;AwB7wJA;EAqCI,kBtBfY;AF2vJhB;;AwBjxJA;EAwCQ,eAAe;AxB6uJvB;;AwBrxJA;EA0CI,iBtBrBW;AFowJf;;AwBzxJA;EA6CQ,eAAe;AxBgvJvB;;AwB7xJA;EAiDM,6BAA6B;EAC7B,0BAA0B;AxBgvJhC;;AwBlyJA;EAoDM,4BAA4B;EAC5B,yBAAyB;AxBkvJ/B;;AwBvyJA;EAwDQ,kBtBDI;AFovJZ;;AwB3yJA;EA0DQ,aAAa;AxBqvJrB;;AwB/yJA;EA6DM,sBAAsB;AxBsvJ5B;;AwBnzJA;EA+DM,sBAAsB;EACtB,YAAY;EACZ,gBAAgB;AxBwvJtB;;AwBzzJA;EAmEM,uBAAuB;AxB0vJ7B;;AwB7zJA;EAqEM,aAAa;EACb,YAAY;AxB4vJlB;;AwBl0JA;EAwEQ,eAAe;AxB8vJvB;;AwBt0JA;EA2EQ,eAAe;AxB+vJvB;;AwB10JA;EA8EQ,eAAe;AxBgwJvB;;AwB90JA;EAiFQ,eAAe;AxBiwJvB;;AwBl1JA;EAoFQ,0BAA4C;AxBkwJpD;;AwBt1JA;EAsFQ,0BtB/BI;EsBgCJ,uBAAuB;AxBowJ/B;;AwB31JA;EAyFI,uBAAuB;AxBswJ3B;;AwB/1JA;EA4FM,WAAW;AxBuwJjB;;AwBn2JA;EA8FM,YAAY;EACZ,eAAe;AxBywJrB;;AwBx2JA;EAiGI,yBAAyB;AxB2wJ7B;;AwB52JA;EAmGM,0BAA4C;AxB6wJlD;;AwBh3JA;EAqGM,0BtB9CM;EsB+CN,2BAA2B;EAC3B,SAAS;AxB+wJf;;AwB7wJA;EACE,oBAAoB;EACpB,aAAa;EACb,eAAe;EACf,2BAA2B;EAC3B,gBAAgB;EAChB,kBAAkB;AxBgxJpB;;AwBtxJA;EASM,yBAA0D;EAC1D,ctB1HwB;AF24J9B;;AwB3xJA;EAYM,qBAAmD;AxBmxJzD;;AwB/xJA;EAeM,yBAAwD;EACxD,ctBhIwB;AFo5J9B;;AwBpyJA;EAkBM,qBAAiD;AxBsxJvD;;AwBpxJA;EACE,YAAY;EACZ,OAAO;EACP,UAAU;EACV,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,WAAW;AxBuxJb;;AwBrxJA;;EAGE,qBtB5I4B;EsB6I5B,kBtBnFU;EsBoFV,cAAc;EACd,iBAAiB;EACjB,kBAAkB;EAClB,mBAAmB;AxBuxJrB;;AwBrxJA;EACE,4BtBlJ4B;EsBmJ5B,ctBxJ4B;AFg7J9B;;AwBtxJA;EACE,qBtBxJ4B;EsByJ5B,mBA1J4B;EA2J5B,2BA1JoC;EA2JpC,cAAc;EACd,eA3JwB;EA4JxB,gBAAgB;EAChB,gBAAgB;EAChB,uBAAuB;AxByxJzB;;AwBvxJA;EACE,mBAAmB;EACnB,aAAa;EACb,WAAW;EACX,uBAAuB;EACvB,mBAAmB;EACnB,UAAU;AxB0xJZ;;AwBhyJA;EAQI,eAAe;AxB4xJnB;;AyB18JA;EACE,cvBA4B;EuBC5B,cAAc;EACd,evB4BW;EuB3BX,gBvBkCe;AF26JjB;;AyBj9JA;EAMI,oBAAoB;AzB+8JxB;;AyBr9JA;EASI,kBvBuBY;AFy7JhB;;AyBz9JA;EAWI,kBvBmBY;AF+7JhB;;AyB79JA;EAaI,iBvBgBW;AFo8Jf;;AyBl9JA;EACE,cAAc;EACd,kBvBec;EuBdd,mBAAmB;AzBq9JrB;;AyBx9JA;EAOM,YvBbyB;AFk+J/B;;AyB59JA;EAOM,cvBzBuB;AFk/J7B;;AyBh+JA;EAOM,iBvBfwB;AF4+J9B;;AyBp+JA;EAOM,cvBrBwB;AFs/J9B;;AyBx+JA;EAOM,cvBR4B;AF6+JlC;;AyB5+JA;EAOM,cvBN4B;AF++JlC;;AyBh/JA;EAOM,cvBP4B;AFo/JlC;;AyBp/JA;EAOM,cvBT4B;AF0/JlC;;AyBx/JA;EAOM,cvBV4B;AF+/JlC;;AyB5/JA;EAOM,cvBJ4B;AF6/JlC;;AyBr/JA;EAEI,sBAAsB;AzBu/J1B;;AyBz/JA;EAKI,aAAa;EACb,2BAA2B;AzBw/J/B;;AyB9/JA;EASQ,kBAAkB;AzBy/J1B;;AyBlgKA;;;EAcU,gBAAgB;AzB0/J1B;;AyBxgKA;;;EAmBU,6BAA6B;EAC7B,0BAA0B;AzB2/JpC;;AyB/gKA;;;EAyBU,4BAA4B;EAC5B,yBAAyB;AzB4/JnC;;AyBthKA;;;;;EAiCY,UAAU;AzB6/JtB;;AyB9hKA;;;;;;;;;EAsCY,UAAU;AzBogKtB;;AyB1iKA;;;;;;;;;EAwCc,UAAU;AzB8gKxB;;AyBtjKA;EA0CQ,YAAY;EACZ,cAAc;AzBghKtB;;AyB3jKA;EA6CM,uBAAuB;AzBkhK7B;;AyB/jKA;EA+CM,yBAAyB;AzBohK/B;;AyBnkKA;EAkDQ,YAAY;EACZ,cAAc;AzBqhKtB;;AyBxkKA;EAqDI,aAAa;EACb,2BAA2B;AzBuhK/B;;AyB7kKA;EAwDM,cAAc;AzByhKpB;;AyBjlKA;EA0DQ,gBAAgB;EAChB,qBAAqB;AzB2hK7B;;AyBtlKA;EA6DQ,YAAY;EACZ,cAAc;AzB6hKtB;;AyB3lKA;EAgEM,uBAAuB;AzB+hK7B;;AyB/lKA;EAkEM,yBAAyB;AzBiiK/B;;AyBnmKA;EAoEM,eAAe;AzBmiKrB;;AyBvmKA;EAwEU,sBAAsB;AzBmiKhC;;AyB3mKA;EA0EQ,uBAAuB;AzBqiK/B;;AyB/mKA;EA4EQ,gBAAgB;AzBuiKxB;;AC7jKE;EwBtDF;IA+EM,aAAa;EzByiKjB;AACF;;AyBxiKA;EAEI,kBAAkB;AzB0iKtB;;AC3kKE;EwB+BF;IAII,qBAAqB;EzB6iKvB;AACF;;AC7kKE;EwB2BF;IAMI,aAAa;IACb,YAAY;IACZ,cAAc;IACd,oBAAoB;IACpB,iBAAiB;EzBijKnB;EyB3jKF;IAYM,kBvBvFU;IuBwFV,oBAAoB;EzBkjKxB;EyB/jKF;IAeM,oBAAoB;EzBmjKxB;EyBlkKF;IAiBM,kBvB9FU;IuB+FV,oBAAoB;EzBojKxB;EyBtkKF;IAoBM,iBvBlGS;IuBmGT,oBAAoB;EzBqjKxB;AACF;;AyBpjKA;EAEI,gBAAgB;AzBsjKpB;;AC1mKE;EwBkDF;IAII,aAAa;IACb,aAAa;IACb,YAAY;IACZ,cAAc;EzByjKhB;EyBhkKF;IASM,gBAAgB;EzB0jKpB;EyBnkKF;IAWM,cAAc;EzB2jKlB;EyBtkKF;IAaQ,YAAY;EzB4jKlB;EyBzkKF;IAeQ,qBAAqB;EzB6jK3B;AACF;;AyB5jKA;EACE,sBAAsB;EACtB,WAAW;EACX,evBvHW;EuBwHX,kBAAkB;EAClB,gBAAgB;AzB+jKlB;;AyBpkKA;;;EAaU,cvB7JoB;AF0tK9B;;AyB1kKA;;;EAeQ,kBvBlIQ;AFmsKhB;;AyBhlKA;;;EAiBQ,kBvBtIQ;AF2sKhB;;AyBtlKA;;;EAmBQ,iBvBzIO;AFktKf;;AyB5lKA;EAqBM,cvBnKwB;EuBoKxB,ctBzKiB;EsB0KjB,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,atB7KiB;EsB8KjB,UAAU;AzB2kKhB;;AyBtmKA;;EA+BM,oBtBlLiB;AH8vKvB;;AyB3mKA;EAiCM,OAAO;AzB8kKb;;AyB/mKA;;EAqCM,qBtBxLiB;AHuwKvB;;AyBpnKA;EAuCM,QAAQ;AzBilKd;;AyBxnKA;EA2CM,6BAA6B;EAC7B,cAAc;EACd,YAAY;EACZ,UAAU;AzBilKhB;;AyB/nKA;EAgDM,kBvBnKU;AFsvKhB;;AyBnoKA;EAkDM,kBvBvKU;AF4vKhB;;AyBvoKA;EAoDM,iBvB1KS;AFiwKf;;A0B1xKA;EAGE,exBwBW;EwBvBX,mBAAmB;A1B2xKrB;;A0B/xKA;EAMI,mBAAmB;EACnB,cxBK8B;EwBJ9B,aAAa;EACb,uBAAuB;EACvB,iBAduC;A1B2yK3C;;A0BvyKA;EAYM,cxBfwB;AF8yK9B;;A0B3yKA;EAcI,mBAAmB;EACnB,aAAa;A1BiyKjB;;A0BhzKA;EAiBM,eAAe;A1BmyKrB;;A0BpzKA;EAoBQ,cxBvBsB;EwBwBtB,eAAe;EACf,oBAAoB;A1BoyK5B;;A0B1zKA;EAwBM,cxBxBwB;EwByBxB,iBAAiB;A1BsyKvB;;A0B/zKA;;EA4BI,uBAAuB;EACvB,aAAa;EACb,eAAe;EACf,2BAA2B;A1BwyK/B;;A0Bv0KA;EAkCM,mBAAmB;A1ByyKzB;;A0B30KA;EAoCM,kBAAkB;A1B2yKxB;;A0B/0KA;;EAyCM,uBAAuB;A1B2yK7B;;A0Bp1KA;;EA6CM,yBAAyB;A1B4yK/B;;A0Bz1KA;EAgDI,kBxBpBY;AFi0KhB;;A0B71KA;EAkDI,kBxBxBY;AFu0KhB;;A0Bj2KA;EAoDI,iBxB3BW;AF40Kf;;A0Br2KA;EAwDM,iBAAiB;A1BizKvB;;A0Bz2KA;EA2DM,iBAAiB;A1BkzKvB;;A0B72KA;EA8DM,iBAAiB;A1BmzKvB;;A0Bj3KA;EAiEM,iBAAiB;A1BozKvB;;A2B32KA;EACE,uBzBN6B;EyBO7B,4EzBnB2B;EyBoB3B,czBf4B;EyBgB5B,eAAe;EACf,kBAAkB;A3B82KpB;;A2B52KA;EACE,6BAvBwC;EAwBxC,oBAAoB;EACpB,2CzB3B2B;EyB4B3B,aAAa;A3B+2Kf;;A2B72KA;EACE,mBAAmB;EACnB,czB5B4B;EyB6B5B,aAAa;EACb,YAAY;EACZ,gBzBMe;EyBLf,gBAhC2B;A3Bg5K7B;;A2Bt3KA;EAQI,uBAAuB;A3Bk3K3B;;A2Bh3KA;EACE,mBAAmB;EACnB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,gBAzC2B;A3B45K7B;;A2Bj3KA;EACE,cAAc;EACd,kBAAkB;A3Bo3KpB;;A2Bl3KA;EACE,6BA5CyC;EA6CzC,eA5C2B;A3Bi6K7B;;A2Bn3KA;EACE,6BA7CwC;EA8CxC,6BzBjD4B;EyBkD5B,oBAAoB;EACpB,aAAa;A3Bs3Kf;;A2Bp3KA;EACE,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,uBAAuB;EACvB,gBAvD2B;A3B86K7B;;A2B93KA;EASI,+BzB9D0B;AFu7K9B;;A2Br3KA;EAEI,qBzB/BkB;AFs5KtB;;A4Bl7KA;EACE,oBAAoB;EACpB,kBAAkB;EAClB,mBAAmB;A5Bq7KrB;;A4Bx7KA;EAOM,cAAc;A5Bq7KpB;;A4B57KA;EAUM,UAAU;EACV,QAAQ;A5Bs7Kd;;A4Bj8KA;EAcM,YAAY;EACZ,mBA9BuB;EA+BvB,oBAAoB;EACpB,SAAS;A5Bu7Kf;;A4Br7KA;EACE,aAAa;EACb,OAAO;EACP,gBAzC6B;EA0C7B,gBAtC2B;EAuC3B,kBAAkB;EAClB,SAAS;EACT,WApCqB;A5B49KvB;;A4Bt7KA;EACE,uB1BlC6B;E0BmC7B,kB1BmBU;E0BlBV,4E1BhD2B;E0BiD3B,sBA9CsC;EA+CtC,mBA9CmC;A5Bu+KrC;;Acn+KgB;Ec6Cd,c1BhD4B;E0BiD5B,cAAc;EACd,mBAAmB;EACnB,gBAAgB;EAChB,sBAAsB;EACtB,kBAAkB;A5B07KpB;;A4Bx7KA;;EAEE,mBAAmB;EACnB,gBAAgB;EAChB,mBAAmB;EACnB,WAAW;A5B27Kb;;A4Bh8KA;;EAOI,4B1BzD0B;E0B0D1B,c1BpEyB;AFkgL7B;;A4Bt8KA;;EAUI,yB1BnD8B;E0BoD9B,WnBZY;AT68KhB;;A4B/7KA;EACE,yB1BlE4B;E0BmE5B,YAAY;EACZ,cAAc;EACd,WAAW;EACX,gBAAgB;A5Bk8KlB;;A6BhhLA;EAEE,mBAAmB;EACnB,8BAA8B;A7BkhLhC;;A6BrhLA;EAKI,kB3B6DQ;AFu9KZ;;A6BzhLA;EAOI,qBAAqB;EACrB,mBAAmB;A7BshLvB;;A6B9hLA;EAWI,aAAa;A7BuhLjB;;A6BliLA;;EAcM,aAAa;A7ByhLnB;;A6BviLA;EAgBM,aAAa;A7B2hLnB;;A6B3iLA;EAmBQ,gBAAgB;EAChB,qBAtBiC;A7BkjLzC;;A6BhjLA;EAsBQ,YAAY;A7B8hLpB;;ACj+KE;E4BnFF;IAyBI,aAAa;E7BgiLf;E6BzjLF;IA4BQ,YAAY;E7BgiLlB;AACF;;A6B/hLA;EACE,mBAAmB;EACnB,aAAa;EACb,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,uBAAuB;A7BkiLzB;;A6BxiLA;;EASI,gBAAgB;A7BoiLpB;;AC5/KE;E4BjDF;IAaM,sBA7CmC;E7BklLvC;AACF;;A6BpiLA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;A7BuiLhB;;A6B3iLA;;EAQM,YAAY;A7BwiLlB;;AC1gLE;E4BtCF;;IAYQ,qBA3DiC;E7BqmLvC;AACF;;A6BziLA;EACE,mBAAmB;EACnB,2BAA2B;A7B4iL7B;;AC1hLE;E4BpBF;IAMM,kBAAkB;E7B6iLtB;AACF;;AC5hLE;E4BxBF;IAQI,aAAa;E7BijLf;AACF;;A6BhjLA;EACE,mBAAmB;EACnB,yBAAyB;A7BmjL3B;;ACviLE;E4BdF;IAKI,aAAa;E7BqjLf;AACF;;A8BxnLA;EAEE,uB5BE6B;E4BD7B,kB5BuDU;E4BtDV,4E5BZ2B;AFsoL7B;;A8BrnLA;EACE,cAAc;EACd,kBAAkB;A9BwnLpB;;A8B1nLA;EAII,c5BhB0B;AF0oL9B;;A8B9nLA;EAMI,2B5B2CQ;E4B1CR,4B5B0CQ;AFklLZ;;A8BnoLA;EASI,8B5BwCQ;E4BvCR,+B5BuCQ;AFulLZ;;A8BxoLA;EAYI,gC5BrB0B;AFqpL9B;;A8B5oLA;EAcI,yB5BZ8B;E4Ba9B,WrB2BY;ATumLhB;;A8BhoLA;EACE,4B5BzB4B;E4B0B5B,eAAe;A9BmoLjB;;A+BzqLA;EACE,uBAAuB;EACvB,aAAa;EACb,gBAAgB;A/B4qLlB;;A+B/qLA;EAKI,sBAAsB;A/B8qL1B;;A+BnrLA;EAOI,8C7BG0B;E6BF1B,aAAa;EACb,oBAAoB;A/BgrLxB;;A+BzrLA;;EAYM,qBAAqB;A/BkrL3B;;A+B9rLA;EAcM,mBAAmB;A/BorLzB;;A+BlsLA;EAgBQ,kBAAkB;A/BsrL1B;;A+BtsLA;EAkBI,8C7BR0B;E6BS1B,gBAAgB;EAChB,iBAAiB;A/BwrLrB;;A+B5sLA;EAwBM,kBAAkB;EAClB,mBAAmB;A/BwrLzB;;A+BtrLA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;A/ByrLhB;;A+BvrLA;EACE,kBAAkB;A/B0rLpB;;A+BxrLA;EACE,iBAAiB;A/B2rLnB;;A+BzrLA;EACE,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,gBAAgB;A/B4rLlB;;ACtpLE;E8B1CF;IAQI,gBAAgB;E/B6rLlB;AACF;;AgC3tLA;EACE,e9BiBW;AF6sLb;;AgC/tLA;EAII,kB9BeY;AFgtLhB;;AgCnuLA;EAMI,kB9BWY;AFstLhB;;AgCvuLA;EAQI,iB9BQW;AF2tLf;;AgCjuLA;EACE,iBArB0B;AhCyvL5B;;AgCruLA;EAGI,kB9BoCc;E8BnCd,c9BzB0B;E8B0B1B,cAAc;EACd,qBAzBiC;AhC+vLrC;;AgC5uLA;EAQM,4B9BxBwB;E8ByBxB,c9B/BwB;AFuwL9B;;AgCjvLA;EAYM,yB9BnB4B;E8BoB5B,WvBoBU;ATqtLhB;;AgCtvLA;EAgBM,8B9BlCwB;E8BmCxB,cAnC0B;EAoC1B,oBAnCgC;AhC6wLtC;;AgCxuLA;EACE,c9BzC4B;E8B0C5B,iBApC2B;EAqC3B,qBApC+B;EAqC/B,yBAAyB;AhC2uL3B;;AgC/uLA;EAMI,eAtCoB;AhCmxLxB;;AgCnvLA;EAQI,kBAxCoB;AhCuxLxB;;AiClxLA;EAEE,4B/BX4B;E+BY5B,kB/B4CU;E+B3CV,e/BWW;AFywLb;;AiCxxLA;EAMI,mBAAmB;AjCsxLvB;;AiC5xLA;EAQI,mBAAmB;EACnB,0BAA0B;AjCwxL9B;;AiCjyLA;EAYI,kB/BIY;AFqxLhB;;AiCryLA;EAcI,kB/BAY;AF2xLhB;;AiCzyLA;EAgBI,iB/BHW;AFgyLf;;AiC7yLA;EA0BM,uBAAmD;AjCuxLzD;;AiCjzLA;EA4BQ,uB/BnCuB;E+BoCvB,c/BhDqB;AFy0L7B;;AiCtzLA;EA+BQ,mB/BtCuB;E+BuCvB,cAA6E;AjC2xLrF;;AiC3zLA;EA0BM,yBAAmD;AjCqyLzD;;AiC/zLA;EA4BQ,yB/B/CqB;E+BgDrB,Y/BpCuB;AF20L/B;;AiCp0LA;EA+BQ,qB/BlDqB;E+BmDrB,cAA6E;AjCyyLrF;;AiCz0LA;EA0BM,yBAAmD;AjCmzLzD;;AiC70LA;EA4BQ,4B/BrCsB;E+BsCtB,c/B5CsB;AFi2L9B;;AiCl1LA;EA+BQ,wB/BxCsB;E+ByCtB,cAA6E;AjCuzLrF;;AiCv1LA;EA0BM,yBAAmD;AjCi0LzD;;AiC31LA;EA4BQ,yB/B3CsB;E+B4CtB,iB/BtCsB;AFy2L9B;;AiCh2LA;EA+BQ,qB/B9CsB;E+B+CtB,cAA6E;AjCq0LrF;;AiCr2LA;EA0BM,yBAAmD;AjC+0LzD;;AiCz2LA;EA4BQ,yB/B9B0B;E+B+B1B,WxBWQ;ATs0LhB;;AiC92LA;EA+BQ,qB/BjC0B;E+BkC1B,cAA6E;AjCm1LrF;;AiCn3LA;EA0BM,yBAAmD;AjC61LzD;;AiCv3LA;EA4BQ,yB/B5B0B;E+B6B1B,WxBWQ;ATo1LhB;;AiC53LA;EA+BQ,qB/B/B0B;E+BgC1B,cAA6E;AjCi2LrF;;AiCj4LA;EA0BM,yBAAmD;AjC22LzD;;AiCr4LA;EA4BQ,yB/B7B0B;E+B8B1B,WxBWQ;ATk2LhB;;AiC14LA;EA+BQ,qB/BhC0B;E+BiC1B,cAA6E;AjC+2LrF;;AiC/4LA;EA0BM,yBAAmD;AjCy3LzD;;AiCn5LA;EA4BQ,yB/B/B0B;E+BgC1B,WxBWQ;ATg3LhB;;AiCx5LA;EA+BQ,qB/BlC0B;E+BmC1B,cAA6E;AjC63LrF;;AiC75LA;EA0BM,yBAAmD;AjCu4LzD;;AiCj6LA;EA4BQ,yB/BhC0B;E+BiC1B,yBxBSa;ATg4LrB;;AiCt6LA;EA+BQ,qB/BnC0B;E+BoC1B,cAA6E;AjC24LrF;;AiC36LA;EA0BM,yBAAmD;AjCq5LzD;;AiC/6LA;EA4BQ,yB/B1B0B;E+B2B1B,WxBWQ;AT44LhB;;AiCp7LA;EA+BQ,qB/B7B0B;E+B8B1B,cAA6E;AjCy5LrF;;AiCv5LA;EACE,mBAAmB;EACnB,yB/BlD4B;E+BmD5B,0BAAgE;EAChE,WxBEc;EwBDd,aAAa;EACb,gB/BlBe;E+BmBf,8BAA8B;EAC9B,iBAAiB;EACjB,mBA1DiC;EA2DjC,kBAAkB;AjC05LpB;;AiCp6LA;EAYI,YAAY;EACZ,cAAc;EACd,mBAAmB;AjC45LvB;;AiC16LA;EAgBI,eArDgC;EAsDhC,yBAAyB;EACzB,0BAA0B;AjC85L9B;;AiC55LA;EACE,qB/BlE4B;E+BmE5B,kB/BTU;E+BUV,mBAAmB;EACnB,uBArEmC;EAsEnC,c/BzE4B;E+B0E5B,qBArEiC;AjCo+LnC;;AiCr6LA;;EASI,uB/BtE2B;AFu+L/B;;AiC16LA;EAWI,6BAtEgD;AjCy+LpD;;AkC39LA;EAEE,mBAAmB;EACnB,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EACvB,gBAAgB;EAChB,eAAe;EACf,WAtCU;AlCmgMZ;;AkCr+LA;EAWI,aAAa;AlC89LjB;;AkC59LA;EAEE,wChC3C2B;AFygM7B;;AkC59LA;;EAEE,cA5CgC;EA6ChC,+BAA0D;EAC1D,cAAc;EACd,kBAAkB;EAClB,WAAW;AlC+9Lb;;AC/7LE;EiCtCF;;IASI,cAAc;IACd,8BAA0D;IAC1D,YAtDuB;ElCwhMzB;AACF;;AkCj+LA;EAEE,gBAAgB;EAChB,YAtD2B;EAuD3B,eAAe;EACf,WAvDsB;EAwDtB,SAvDoB;EAwDpB,WA1D2B;AlC6hM7B;;AkCj+LA;EACE,aAAa;EACb,sBAAsB;EACtB,8BAAgD;EAChD,gBAAgB;EAChB,uBAAuB;AlCo+LzB;;AkCl+LA;;EAEE,mBAAmB;EACnB,4BhCnE4B;EgCoE5B,aAAa;EACb,cAAc;EACd,2BAA2B;EAC3B,aAlE4B;EAmE5B,kBAAkB;AlCq+LpB;;AkCn+LA;EACE,gChC7E4B;EgC8E5B,2BhCnBgB;EgCoBhB,4BhCpBgB;AF0/LlB;;AkCp+LA;EACE,chCtF4B;EgCuF5B,YAAY;EACZ,cAAc;EACd,iBhC7Da;EgC8Db,cA3E8B;AlCkjMhC;;AkCr+LA;EACE,8BhC9BgB;EgC+BhB,+BhC/BgB;EgCgChB,6BhC3F4B;AFmkM9B;;AkC3+LA;EAMM,mBAAmB;AlCy+LzB;;AkCv+LA;EjC5CE,iCAAiC;EiC8CjC,uBhC9F6B;EgC+F7B,YAAY;EACZ,cAAc;EACd,cAAc;EACd,aApF4B;AlC8jM9B;;AmCpiMA;EACE,uBjCzC6B;EiC0C7B,mBArDqB;EAsDrB,kBAAkB;EAClB,WApDW;AnC2lMb;;AmC3iMA;EASM,uBjCjDyB;EiCkDzB,cjC9DuB;AFomM7B;;AmChjMA;;EAcU,cjClEmB;AFymM7B;;AmCrjMA;;;;EAoBY,yBAAoC;EACpC,cjCzEiB;AFinM7B;;AmC7jMA;EAwBY,qBjC5EiB;AFqnM7B;;AmCjkMA;EA0BQ,cjC9EqB;AFynM7B;;ACljME;EkCnBF;;;;IAgCY,cjCpFiB;EFioM3B;EmC7kMF;;;;;;;;;;IAsCc,yBAAoC;IACpC,cjC3Fe;EF8oM3B;EmC1lMF;;IA0Cc,qBjC9Fe;EFkpM3B;EmC9lMF;;;IA8CU,yBAAoC;IACpC,cjCnGmB;EFwpM3B;EmCpmMF;IAmDc,uBjC3FiB;IiC4FjB,cjCxGe;EF4pM3B;AACF;;AmCzmMA;EASM,yBjC7DuB;EiC8DvB,YjClDyB;AFspM/B;;AmC9mMA;;EAcU,YjCtDqB;AF2pM/B;;AmCnnMA;;;;EAoBY,uBAAoC;EACpC,YjC7DmB;AFmqM/B;;AmC3nMA;EAwBY,mBjChEmB;AFuqM/B;;AmC/nMA;EA0BQ,YjClEuB;AF2qM/B;;AChnME;EkCnBF;;;;IAgCY,YjCxEmB;EFmrM7B;EmC3oMF;;;;;;;;;;IAsCc,uBAAoC;IACpC,YjC/EiB;EFgsM7B;EmCxpMF;;IA0Cc,mBjClFiB;EFosM7B;EmC5pMF;;;IA8CU,uBAAoC;IACpC,YjCvFqB;EF0sM7B;EmClqMF;IAmDc,yBjCvGe;IiCwGf,YjC5FiB;EF8sM7B;AACF;;AmCvqMA;EASM,4BjCnDwB;EiCoDxB,cjC1DwB;AF4tM9B;;AmC5qMA;;EAcU,cjC9DoB;AFiuM9B;;AmCjrMA;;;;EAoBY,yBAAoC;EACpC,cjCrEkB;AFyuM9B;;AmCzrMA;EAwBY,qBjCxEkB;AF6uM9B;;AmC7rMA;EA0BQ,cjC1EsB;AFivM9B;;AC9qME;EkCnBF;;;;IAgCY,cjChFkB;EFyvM5B;EmCzsMF;;;;;;;;;;IAsCc,yBAAoC;IACpC,cjCvFgB;EFswM5B;EmCttMF;;IA0Cc,qBjC1FgB;EF0wM5B;EmC1tMF;;;IA8CU,yBAAoC;IACpC,cjC/FoB;EFgxM5B;EmChuMF;IAmDc,4BjC7FgB;IiC8FhB,cjCpGgB;EFoxM5B;AACF;;AmCruMA;EASM,yBjCzDwB;EiC0DxB,iBjCpDwB;AFoxM9B;;AmC1uMA;;EAcU,iBjCxDoB;AFyxM9B;;AmC/uMA;;;;EAoBY,yBAAoC;EACpC,iBjC/DkB;AFiyM9B;;AmCvvMA;EAwBY,wBjClEkB;AFqyM9B;;AmC3vMA;EA0BQ,iBjCpEsB;AFyyM9B;;AC5uME;EkCnBF;;;;IAgCY,iBjC1EkB;EFizM5B;EmCvwMF;;;;;;;;;;IAsCc,yBAAoC;IACpC,iBjCjFgB;EF8zM5B;EmCpxMF;;IA0Cc,wBjCpFgB;EFk0M5B;EmCxxMF;;;IA8CU,yBAAoC;IACpC,iBjCzFoB;EFw0M5B;EmC9xMF;IAmDc,yBjCnGgB;IiCoGhB,iBjC9FgB;EF40M5B;AACF;;AmCnyMA;EASM,yBjC5C4B;EiC6C5B,W1BHU;ATiyMhB;;AmCxyMA;;EAcU,W1BPM;ATsyMhB;;AmC7yMA;;;;EAoBY,yBAAoC;EACpC,W1BdI;AT8yMhB;;AmCrzMA;EAwBY,kB1BjBI;ATkzMhB;;AmCzzMA;EA0BQ,W1BnBQ;ATszMhB;;AC1yME;EkCnBF;;;;IAgCY,W1BzBI;ET8zMd;EmCr0MF;;;;;;;;;;IAsCc,yBAAoC;IACpC,W1BhCE;ET20Md;EmCl1MF;;IA0Cc,kB1BnCE;ET+0Md;EmCt1MF;;;IA8CU,yBAAoC;IACpC,W1BxCM;ETq1Md;EmC51MF;IAmDc,yBjCtFoB;IiCuFpB,W1B7CE;ETy1Md;AACF;;AmCj2MA;EASM,yBjC1C4B;EiC2C5B,W1BHU;AT+1MhB;;AmCt2MA;;EAcU,W1BPM;ATo2MhB;;AmC32MA;;;;EAoBY,yBAAoC;EACpC,W1BdI;AT42MhB;;AmCn3MA;EAwBY,kB1BjBI;ATg3MhB;;AmCv3MA;EA0BQ,W1BnBQ;ATo3MhB;;ACx2ME;EkCnBF;;;;IAgCY,W1BzBI;ET43Md;EmCn4MF;;;;;;;;;;IAsCc,yBAAoC;IACpC,W1BhCE;ETy4Md;EmCh5MF;;IA0Cc,kB1BnCE;ET64Md;EmCp5MF;;;IA8CU,yBAAoC;IACpC,W1BxCM;ETm5Md;EmC15MF;IAmDc,yBjCpFoB;IiCqFpB,W1B7CE;ETu5Md;AACF;;AmC/5MA;EASM,yBjC3C4B;EiC4C5B,W1BHU;AT65MhB;;AmCp6MA;;EAcU,W1BPM;ATk6MhB;;AmCz6MA;;;;EAoBY,yBAAoC;EACpC,W1BdI;AT06MhB;;AmCj7MA;EAwBY,kB1BjBI;AT86MhB;;AmCr7MA;EA0BQ,W1BnBQ;ATk7MhB;;ACt6ME;EkCnBF;;;;IAgCY,W1BzBI;ET07Md;EmCj8MF;;;;;;;;;;IAsCc,yBAAoC;IACpC,W1BhCE;ETu8Md;EmC98MF;;IA0Cc,kB1BnCE;ET28Md;EmCl9MF;;;IA8CU,yBAAoC;IACpC,W1BxCM;ETi9Md;EmCx9MF;IAmDc,yBjCrFoB;IiCsFpB,W1B7CE;ETq9Md;AACF;;AmC79MA;EASM,yBjC7C4B;EiC8C5B,W1BHU;AT29MhB;;AmCl+MA;;EAcU,W1BPM;ATg+MhB;;AmCv+MA;;;;EAoBY,yBAAoC;EACpC,W1BdI;ATw+MhB;;AmC/+MA;EAwBY,kB1BjBI;AT4+MhB;;AmCn/MA;EA0BQ,W1BnBQ;ATg/MhB;;ACp+ME;EkCnBF;;;;IAgCY,W1BzBI;ETw/Md;EmC//MF;;;;;;;;;;IAsCc,yBAAoC;IACpC,W1BhCE;ETqgNd;EmC5gNF;;IA0Cc,kB1BnCE;ETygNd;EmChhNF;;;IA8CU,yBAAoC;IACpC,W1BxCM;ET+gNd;EmCthNF;IAmDc,yBjCvFoB;IiCwFpB,W1B7CE;ETmhNd;AACF;;AmC3hNA;EASM,yBjC9C4B;EiC+C5B,yB1BLe;AT2hNrB;;AmChiNA;;EAcU,yB1BTW;ATgiNrB;;AmCriNA;;;;EAoBY,yBAAoC;EACpC,yB1BhBS;ATwiNrB;;AmC7iNA;EAwBY,gC1BnBS;AT4iNrB;;AmCjjNA;EA0BQ,yB1BrBa;ATgjNrB;;ACliNE;EkCnBF;;;;IAgCY,yB1B3BS;ETwjNnB;EmC7jNF;;;;;;;;;;IAsCc,yBAAoC;IACpC,yB1BlCO;ETqkNnB;EmC1kNF;;IA0Cc,gC1BrCO;ETykNnB;EmC9kNF;;;IA8CU,yBAAoC;IACpC,yB1B1CW;ET+kNnB;EmCplNF;IAmDc,yBjCxFoB;IiCyFpB,yB1B/CO;ETmlNnB;AACF;;AmCzlNA;EASM,yBjCxC4B;EiCyC5B,W1BHU;ATulNhB;;AmC9lNA;;EAcU,W1BPM;AT4lNhB;;AmCnmNA;;;;EAoBY,yBAAoC;EACpC,W1BdI;ATomNhB;;AmC3mNA;EAwBY,kB1BjBI;ATwmNhB;;AmC/mNA;EA0BQ,W1BnBQ;AT4mNhB;;AChmNE;EkCnBF;;;;IAgCY,W1BzBI;ETonNd;EmC3nNF;;;;;;;;;;IAsCc,yBAAoC;IACpC,W1BhCE;ETioNd;EmCxoNF;;IA0Cc,kB1BnCE;ETqoNd;EmC5oNF;;;IA8CU,yBAAoC;IACpC,W1BxCM;ET2oNd;EmClpNF;IAmDc,yBjClFoB;IiCmFpB,W1B7CE;ET+oNd;AACF;;AmCvpNA;EAsDI,oBAAoB;EACpB,aAAa;EACb,mBA3GmB;EA4GnB,WAAW;AnCqmNf;;AmC9pNA;EA2DI,gCjCrG0B;AF4sN9B;;AmClqNA;EALE,OAAO;EACP,eAAe;EACf,QAAQ;EACR,WA7CiB;AnCwtNnB;;AmCzqNA;EAgEI,SAAS;AnC6mNb;;AmC7qNA;EAkEM,iCjC5GwB;AF2tN9B;;AmCjrNA;EAoEI,MAAM;AnCinNV;;AmC/mNA;;EAGI,oBA5HmB;AnC6uNvB;;AmCpnNA;;EAKI,uBA9HmB;AnCkvNvB;;AmClnNA;;EAEE,oBAAoB;EACpB,aAAa;EACb,cAAc;EACd,mBArIqB;AnC0vNvB;;AmCnnNA;EAIM,6BAA6B;AnCmnNnC;;AmCjnNA;ElClFE,iCAAiC;EkCoFjC,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;AnConNpB;;AmClnNA;EACE,cjChJ4B;EDoB5B,eAAe;EACf,cAAc;EACd,ekC1BqB;ElC2BrB,kBAAkB;EAClB,ckC5BqB;EAsJrB,iBAAiB;AnCynNnB;;AClvNE;EACE,8BAA8B;EAC9B,cAAc;EACd,WAAW;EACX,qBAAqB;EACrB,kBAAkB;EAClB,gCAAwB;UAAxB,wBAAwB;EACxB,yBCgCQ;ED/BR,iEAAyD;EAAzD,yDAAyD;EAAzD,4EAAyD;EACzD,oCCyBa;EDxBb,WAAW;ADqvNf;;ACpvNI;EACE,oBAAoB;ADuvN1B;;ACtvNI;EACE,oBAAoB;ADyvN1B;;ACxvNI;EACE,oBAAoB;AD2vN1B;;AC1vNE;EACE,qCAA4B;AD6vNhC;;ACzvNM;EACE,gDAAwC;UAAxC,wCAAwC;AD4vNhD;;AC3vNM;EACE,UAAU;AD8vNlB;;AC7vNM;EACE,kDAA0C;UAA1C,0CAA0C;ADgwNlD;;AmChqNA;EACE,aAAa;AnCmqNf;;AmCjqNA;;EAEE,cjCzJ4B;EiC0J5B,cAAc;EACd,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;AnCoqNpB;;AmC1qNA;;EASM,qBAAqB;EACrB,sBAAsB;AnCsqN5B;;AmCpqNA;;EAEE,eAAe;AnCuqNjB;;AmCzqNA;;;;;EAOI,yBjCpK0B;EiCqK1B,cjC7J8B;AFu0NlC;;AmCxqNA;EACE,cAAc;EACd,YAAY;EACZ,cAAc;AnC2qNhB;;AmC9qNA;EAKI,mBA3KgC;AnCw1NpC;;AmClrNA;EAOI,UAAU;AnC+qNd;;AmCtrNA;EASI,YAAY;EACZ,cAAc;AnCirNlB;;AmC3rNA;EAYI,oCAAoC;EACpC,mBA9LmB;EA+LnB,kCAAkC;AnCmrNtC;;AmCjsNA;EAiBM,6BAnLyC;EAoLzC,4BjCjL4B;AFq2NlC;;AmCtsNA;EAoBM,6BAnL0C;EAoL1C,4BjCpL4B;EiCqL5B,0BAnLuC;EAoLvC,wBAnLqC;EAoLrC,cjCvL4B;EiCwL5B,kCAAwE;AnCsrN9E;;AmCprNA;EACE,YAAY;EACZ,cAAc;AnCurNhB;;AmCrrNA;EACE,oBAAoB;AnCwrNtB;;AmCzrNA;EAII,qBjClM8B;EiCmM9B,oBAAoB;EACpB,cAAc;AnCyrNlB;;AmCvrNA;EACE,mBAAmB;EACnB,sBAAsB;EACtB,mBAAmB;AnC0rNrB;;AmC7rNA;EAKI,oBAAoB;EACpB,qBAAqB;AnC4rNzB;;AmC1rNA;EACE,4BjCxN4B;EiCyN5B,YAAY;EACZ,aAAa;EACb,WA7LyB;EA8LzB,gBAAgB;AnC6rNlB;;ACx1NE;EkCvBF;IAsLI,cAAc;EnC8rNhB;EmC7rNA;;IAGI,mBAAmB;IACnB,aAAa;EnC8rNjB;EmC7rNA;IAEI,aAAa;EnC8rNjB;EmCvxNF;IA2FI,uBjCxO2B;IiCyO3B,4CjCrPyB;IiCsPzB,iBAAiB;EnC+rNnB;EmClsNA;IAKI,cAAc;EnCgsNlB;EmC9rNA;IA3MA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA7CiB;EnCy7NjB;EmCpsNA;IAKI,SAAS;EnCksNb;EmCvsNA;IAOM,4CjCjQqB;EFo8N3B;EmC1sNA;IASI,MAAM;EnCosNV;EmC7sNA;IlC9LA,iCAAiC;IkC4M3B,iCAA2C;IAC3C,cAAc;EnCmsNpB;EmClsNA;;IAGI,oBA5QiB;EnC+8NrB;EmCtsNA;;IAKI,uBA9QiB;EnCm9NrB;AACF;;AC94NE;EkC2MA;;;;IAIE,oBAAoB;IACpB,aAAa;EnCusNf;EmC16NF;IAqOI,mBAxRmB;EnCg+NrB;EmCzsNA;IAGI,kBAxR0B;EnCi+N9B;EmC5sNA;;IAMM,mBAAmB;EnC0sNzB;EmChtNA;;IASM,kBjC/NI;EF06NV;EmCptNA;;;;IAgBQ,wCAAwC;EnC0sNhD;EmC1tNA;IAuBU,wCAAwC;EnCssNlD;EmC7tNA;IA4BU,4BjC1SkB;IiC2SlB,cjCrTiB;EFy/N3B;EmCjuNA;IA+BU,4BjC7SkB;IiC8SlB,cjCrSsB;EF0+NhC;EmCz2NF;IAsKI,aAAa;EnCssNf;EmCp2NF;;IAiKI,mBAAmB;IACnB,aAAa;EnCusNf;EmCn1NF;IA8II,aAAa;EnCwsNf;EmCt1NF;IAgJM,oBAAoB;EnCysNxB;EmC5sNA;IAMM,4DAAoD;YAApD,oDAAoD;EnCysN1D;EmC/sNA;IAQM,gCjC/TsB;IiCgUtB,0BAAkE;IAClE,gBAAgB;IAChB,YAAY;IACZ,4CjC3UqB;IiC4UrB,SAAS;EnC0sNf;EmCvtNA;IAmBM,cAAc;EnCusNpB;EmCtsNM;IAEE,UAAU;IACV,oBAAoB;IACpB,gCAAwB;YAAxB,wBAAwB;EnCusNhC;EmCr4NF;IAgMI,YAAY;IACZ,cAAc;EnCwsNhB;EmCvsNA;IACE,2BAA2B;IAC3B,kBAAkB;EnCysNpB;EmCxsNA;IACE,yBAAyB;IACzB,iBAAiB;EnC0sNnB;EmCj1NF;IAyII,uBjCtV2B;IiCuV3B,8BjChSc;IiCiSd,+BjCjSc;IiCkSd,6BjC7V0B;IiC8V1B,2CjCtWyB;IiCuWzB,aAAa;IACb,mBAAmB;IACnB,OAAO;IACP,eAAe;IACf,kBAAkB;IAClB,SAAS;IACT,WAhVkB;EnC2hOpB;EmC/1NF;IAsJM,sBAAsB;IACtB,mBAAmB;EnC4sNvB;EmC3tNA;IAiBI,mBAAmB;EnC6sNvB;EmC9tNA;IAoBM,4BjC3WsB;IiC4WtB,cjCtXqB;EFmkO3B;EmCluNA;IAuBM,4BjC9WsB;IiC+WtB,cjCtW0B;EFojOhC;EmC7sNE;IAEE,kBjCzTY;IiC0TZ,gBAAgB;IAChB,4EjC9XuB;IiC+XvB,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,wBAA8C;IAC9C,mCAA2B;YAA3B,2BAA2B;IAC3B,yBjC/TM;IiCgUN,+CAAuC;IAAvC,uCAAuC;IAAvC,0DAAuC;EnC8sN3C;EmClvNA;IAsCI,UAAU;IACV,QAAQ;EnC+sNZ;EmCt3NF;IAyKI,cAAc;EnCgtNhB;EmC/sNA;;IAGI,oBAAoB;EnCgtNxB;EmCntNA;;IAKI,qBAAqB;EnCktNzB;EmChtNA;IAnWA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA7CiB;EnCmmOjB;EmCttNA;IAKI,SAAS;EnCotNb;EmCztNA;IAOM,4CjCzZqB;EF8mO3B;EmC5tNA;IASI,MAAM;EnCstNV;EmCrtNA;;IAGI,oBA9ZiB;EnConOrB;EmCztNA;;IAKI,uBAhaiB;EnCwnOrB;EmC7tNA;;IAOI,oBAA4D;EnC0tNhE;EmCjuNA;;IASI,uBAA+D;EnC4tNnE;EmC1tNA;;IAGI,cjC1auB;EFqoO3B;EmC9tNA;;IAKI,6BAja2C;EnC8nO/C;EmC5tNA;IAKM,yBjCvasB;EFioO5B;AACF;;AmCvtNA;EAEI,iCAA2C;AnCytN/C;;AoCpnOA;EACE,elCIW;EkCHX,gBA/B0B;ApCspO5B;;AoCznOA;EAKI,kBlCCY;AFunOhB;;AoC7nOA;EAOI,kBlCHY;AF6nOhB;;AoCjoOA;EASI,iBlCNW;AFkoOf;;AoCroOA;;EAaM,iBAAiB;EACjB,kBAAkB;EAClB,uBlCwBmB;AFqmOzB;;AoC5oOA;EAiBM,uBlCsBmB;AFymOzB;;AoC7nOA;;EAEE,mBAAmB;EACnB,aAAa;EACb,uBAAuB;EACvB,kBAAkB;ApCgoOpB;;AoC9nOA;;;;EAME,cA1D6B;EA2D7B,uBAAuB;EACvB,eA3D8B;EA4D9B,mBA3DkC;EA4DlC,oBA3DmC;EA4DnC,kBAAkB;ApC+nOpB;;AoC7nOA;;;EAGE,qBlC/D4B;EkCgE5B,clCpE4B;EkCqE5B,iBjCtEqB;AHssOvB;;AoCroOA;;;EAOI,qBlCpE0B;EkCqE1B,clCxE0B;AF4sO9B;;AoC5oOA;;;EAUI,qBlC3D8B;AFmsOlC;;AoClpOA;;;EAYI,iDlChFyB;AF4tO7B;;AoCxpOA;;;EAcI,yBlC1E0B;EkC2E1B,qBlC3E0B;EkC4E1B,gBAAgB;EAChB,clC/E0B;EkCgF1B,YAAY;ApCgpOhB;;AoC9oOA;;EAEE,oBAAoB;EACpB,qBAAqB;EACrB,mBAAmB;ApCipOrB;;AoC/oOA;EAEI,yBlC7E8B;EkC8E9B,qBlC9E8B;EkC+E9B,W3BvCY;ATwrOhB;;AoC/oOA;EACE,clC9F4B;EkC+F5B,oBAAoB;ApCkpOtB;;AoChpOA;EACE,eAAe;ApCmpOjB;;AC7qOE;EmClDF;IAgFI,eAAe;EpCopOjB;EoCzqOF;;IAwBI,YAAY;IACZ,cAAc;EpCqpOhB;EoCppOA;IAEI,YAAY;IACZ,cAAc;EpCqpOlB;AACF;;ACxrOE;EmCqBF;IAiBI,YAAY;IACZ,cAAc;IACd,2BAA2B;IAC3B,QAAQ;EpCupOV;EoCtpOA;IACE,QAAQ;EpCwpOV;EoCvpOA;IACE,QAAQ;EpCypOV;EoC5vOF;IAqGI,8BAA8B;EpC0pOhC;EoC3pOA;IAIM,QAAQ;EpC0pOd;EoC9pOA;IAMM,uBAAuB;IACvB,QAAQ;EpC2pOd;EoClqOA;IASM,QAAQ;EpC4pOd;EoCrqOA;IAYM,QAAQ;EpC4pOd;EoCxqOA;IAcM,QAAQ;EpC6pOd;EoC3qOA;IAgBM,yBAAyB;IACzB,QAAQ;EpC8pOd;AACF;;AqCxxOA;EACE,enCQW;AFmxOb;;AqC5xOA;EAGI,qBnCiBkB;AF4wOtB;;AqC3xOA;;;EAGE,gCnCzB4B;EmC0B5B,8BnC1B4B;EmC2B5B,+BnC3B4B;AFyzO9B;;AqCnyOA;;;EAOI,6BnC7B0B;AF+zO9B;;AqChyOA;EACE,4BnC9B4B;EmC+B5B,0BAA8D;EAC9D,cnCtC4B;EmCuC5B,iBArCyB;EAsCzB,gBnCPgB;EmCQhB,iBA1C8B;EA2C9B,qBA1CkC;ArC60OpC;;AqCjyOA;EACE,qBAAqB;EACrB,aAAa;EACb,kBA1C4B;EA2C5B,uBAAuB;ArCoyOzB;;AqCxyOA;EAMI,gCnC9C0B;EmC+C1B,mBAAmB;EACnB,cAAc;ArCsyOlB;;AqC9yOA;EAWM,4BnCtDwB;EmCuDxB,cnCxDwB;AF+1O9B;;AqCryOA;EAEI,cnC3D0B;AFk2O9B;;AqCzyOA;EAIM,cnC/C4B;AFw1OlC;;AqCvyOA;EACE,mBAAmB;EACnB,cnClE4B;EmCmE5B,aAAa;EACb,2BAA2B;EAC3B,qBAAqB;ArC0yOvB;;AqC/yOA;EAOI,oBAAoB;ArC4yOxB;;AqCnzOA;EASI,YAAY;EACZ,cAAc;EACd,WAAW;ArC8yOf;;AqCzzOA;EAaI,eAAe;ArCgzOnB;;AqC7zOA;EAeI,0BnChE8B;EmCiE9B,cnChF0B;AFk4O9B;;AqCl0OA;EAkBM,cnCnE4B;AFu3OlC;;AqClzOA;;EAEE,eAAe;ArCqzOjB;;AqCvzOA;;EAII,4BnClF0B;AF04O9B;;AqCtzOA;EpC9EE,qBAAqB;EACrB,eoC8EgB;EpC7EhB,WoC6EqB;EpC5ErB,gBoC4EqB;EpC3ErB,kBAAkB;EAClB,mBAAmB;EACnB,UoCyEqB;EACrB,cnC1F4B;EmC2F5B,oBAAoB;ArC+zOtB;;AqCl0OA;EAKI,kBAAkB;EAClB,oBAAoB;ArCi0OxB;;AsC34OA;ErCkCE,iCAAiC;EqC9BjC,oBAAoB;EACpB,aAAa;EACb,epCEW;EoCDX,8BAA8B;EAC9B,gBAAgB;EAChB,gBAAgB;EAChB,mBAAmB;AtC44OrB;;AsCt5OA;EAYI,mBAAmB;EACnB,4BpC/B0B;EoCgC1B,0BAzC4B;EA0C5B,wBAzC0B;EA0C1B,cpCrC0B;EoCsC1B,aAAa;EACb,uBAAuB;EACvB,mBAA6C;EAC7C,kBAxCyB;EAyCzB,mBAAmB;AtC84OvB;;AsCn6OA;EAuBM,4BpC7CwB;EoC8CxB,cpC9CwB;AF87O9B;;AsCx6OA;EA0BI,cAAc;AtCk5OlB;;AsC56OA;EA6BQ,4BpCpC0B;EoCqC1B,cpCrC0B;AFw7OlC;;AsCj7OA;EAgCI,mBAAmB;EACnB,4BpCnD0B;EoCoD1B,0BA7D4B;EA8D5B,wBA7D0B;EA8D1B,aAAa;EACb,YAAY;EACZ,cAAc;EACd,2BAA2B;AtCq5O/B;;AsC57OA;EAyCM,qBAAqB;AtCu5O3B;;AsCh8OA;EA2CM,UAAU;EACV,uBAAuB;EACvB,oBAAoB;EACpB,qBAAqB;AtCy5O3B;;AsCv8OA;EAgDM,yBAAyB;EACzB,oBAAoB;AtC25O1B;;AsC58OA;EAoDM,mBAAmB;AtC45OzB;;AsCh9OA;EAsDM,kBAAkB;AtC85OxB;;AsCp9OA;EA0DM,uBAAuB;AtC85O7B;;AsCx9OA;EA6DM,yBAAyB;AtC+5O/B;;AsC59OA;EAiEM,6BAA6B;EAC7B,0BAAkE;AtC+5OxE;;AsCj+OA;EAoEQ,4BpCpFsB;EoCqFtB,4BpCvFsB;AFw/O9B;;AsCt+OA;EAyEU,uBpCvFqB;EoCwFrB,qBpC5FoB;EoC6FpB,2CAA2E;AtCi6OrF;;AsC5+OA;EA8EM,YAAY;EACZ,cAAc;AtCk6OpB;;AsCj/OA;EAkFM,qBpCpGwB;EoCqGxB,mBA5F+B;EA6F/B,iBA5F6B;EA6F7B,gBAAgB;EAChB,kBAAkB;AtCm6OxB;;AsCz/OA;EAwFQ,4BpCxGsB;EoCyGtB,qBpC5GsB;EoC6GtB,UAAU;AtCq6OlB;;AsC//OA;EA6FQ,iBAAgD;AtCs6OxD;;AsCngPA;EA+FQ,0BpCvDI;AF+9OZ;;AsCvgPA;EAiGQ,0BAAoE;AtC06O5E;;AsC3gPA;EAoGU,yBpC3GwB;EoC4GxB,qBpC5GwB;EoC6GxB,W7BrEM;E6BsEN,UAAU;AtC26OpB;;AsClhPA;EAyGM,mBAAmB;AtC66OzB;;AsCthPA;EA6GU,mCpCnEe;EoCoEf,gCpCpEe;EoCqEf,oBAAoB;AtC66O9B;;AsC5hPA;EAiHU,oCpCvEe;EoCwEf,iCpCxEe;EoCyEf,qBAAqB;AtC+6O/B;;AsCliPA;EAsHI,kBpC7GY;AF6hPhB;;AsCtiPA;EAwHI,kBpCjHY;AFmiPhB;;AsC1iPA;EA0HI,iBpCpHW;AFwiPf;;AuCxkPA;EACE,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAPkB;AvCklPpB;;AuC1kPE;EACE,UAAU;AvC6kPd;;AuC5kPE;EACE,UAAU;EACV,WAAW;AvC+kPf;;AuC9kPE;EACE,UAAU;EACV,UAAU;AvCilPd;;AuChlPE;EACE,UAAU;EACV,eAAe;AvCmlPnB;;AuCllPE;EACE,UAAU;EACV,UAAU;AvCqlPd;;AuCplPE;EACE,UAAU;EACV,eAAe;AvCulPnB;;AuCtlPE;EACE,UAAU;EACV,UAAU;AvCylPd;;AuCxlPE;EACE,UAAU;EACV,UAAU;AvC2lPd;;AuC1lPE;EACE,UAAU;EACV,UAAU;AvC6lPd;;AuC5lPE;EACE,UAAU;EACV,UAAU;AvC+lPd;;AuC9lPE;EACE,UAAU;EACV,UAAU;AvCimPd;;AuChmPE;EACE,gBAAgB;AvCmmPpB;;AuClmPE;EACE,qBAAqB;AvCqmPzB;;AuCpmPE;EACE,gBAAgB;AvCumPpB;;AuCtmPE;EACE,qBAAqB;AvCymPzB;;AuCxmPE;EACE,gBAAgB;AvC2mPpB;;AuC1mPE;EACE,gBAAgB;AvC6mPpB;;AuC5mPE;EACE,gBAAgB;AvC+mPpB;;AuC9mPE;EACE,gBAAgB;AvCinPpB;;AuChnPE;EACE,gBAAgB;AvCmnPpB;;AuCjnPI;EACE,UAAU;EACV,SAA0B;AvConPhC;;AuCnnPI;EACE,eAAgC;AvCsnPtC;;AuC1nPI;EACE,UAAU;EACV,eAA0B;AvC6nPhC;;AuC5nPI;EACE,qBAAgC;AvC+nPtC;;AuCnoPI;EACE,UAAU;EACV,gBAA0B;AvCsoPhC;;AuCroPI;EACE,sBAAgC;AvCwoPtC;;AuC5oPI;EACE,UAAU;EACV,UAA0B;AvC+oPhC;;AuC9oPI;EACE,gBAAgC;AvCipPtC;;AuCrpPI;EACE,UAAU;EACV,gBAA0B;AvCwpPhC;;AuCvpPI;EACE,sBAAgC;AvC0pPtC;;AuC9pPI;EACE,UAAU;EACV,gBAA0B;AvCiqPhC;;AuChqPI;EACE,sBAAgC;AvCmqPtC;;AuCvqPI;EACE,UAAU;EACV,UAA0B;AvC0qPhC;;AuCzqPI;EACE,gBAAgC;AvC4qPtC;;AuChrPI;EACE,UAAU;EACV,gBAA0B;AvCmrPhC;;AuClrPI;EACE,sBAAgC;AvCqrPtC;;AuCzrPI;EACE,UAAU;EACV,gBAA0B;AvC4rPhC;;AuC3rPI;EACE,sBAAgC;AvC8rPtC;;AuClsPI;EACE,UAAU;EACV,UAA0B;AvCqsPhC;;AuCpsPI;EACE,gBAAgC;AvCusPtC;;AuC3sPI;EACE,UAAU;EACV,gBAA0B;AvC8sPhC;;AuC7sPI;EACE,sBAAgC;AvCgtPtC;;AuCptPI;EACE,UAAU;EACV,gBAA0B;AvCutPhC;;AuCttPI;EACE,sBAAgC;AvCytPtC;;AuC7tPI;EACE,UAAU;EACV,WAA0B;AvCguPhC;;AuC/tPI;EACE,iBAAgC;AvCkuPtC;;AChtPE;EsC/EF;IAgEM,UAAU;EvCouPd;EuCpyPF;IAkEM,UAAU;IACV,WAAW;EvCquPf;EuCxyPF;IAqEM,UAAU;IACV,UAAU;EvCsuPd;EuC5yPF;IAwEM,UAAU;IACV,eAAe;EvCuuPnB;EuChzPF;IA2EM,UAAU;IACV,UAAU;EvCwuPd;EuCpzPF;IA8EM,UAAU;IACV,eAAe;EvCyuPnB;EuCxzPF;IAiFM,UAAU;IACV,UAAU;EvC0uPd;EuC5zPF;IAoFM,UAAU;IACV,UAAU;EvC2uPd;EuCh0PF;IAuFM,UAAU;IACV,UAAU;EvC4uPd;EuCp0PF;IA0FM,UAAU;IACV,UAAU;EvC6uPd;EuCx0PF;IA6FM,UAAU;IACV,UAAU;EvC8uPd;EuC50PF;IAgGM,gBAAgB;EvC+uPpB;EuC/0PF;IAkGM,qBAAqB;EvCgvPzB;EuCl1PF;IAoGM,gBAAgB;EvCivPpB;EuCr1PF;IAsGM,qBAAqB;EvCkvPzB;EuCx1PF;IAwGM,gBAAgB;EvCmvPpB;EuC31PF;IA0GM,gBAAgB;EvCovPpB;EuC91PF;IA4GM,gBAAgB;EvCqvPpB;EuCj2PF;IA8GM,gBAAgB;EvCsvPpB;EuCp2PF;IAgHM,gBAAgB;EvCuvPpB;EuCv2PF;IAmHQ,UAAU;IACV,SAA0B;EvCuvPhC;EuC32PF;IAsHQ,eAAgC;EvCwvPtC;EuC92PF;IAmHQ,UAAU;IACV,eAA0B;EvC8vPhC;EuCl3PF;IAsHQ,qBAAgC;EvC+vPtC;EuCr3PF;IAmHQ,UAAU;IACV,gBAA0B;EvCqwPhC;EuCz3PF;IAsHQ,sBAAgC;EvCswPtC;EuC53PF;IAmHQ,UAAU;IACV,UAA0B;EvC4wPhC;EuCh4PF;IAsHQ,gBAAgC;EvC6wPtC;EuCn4PF;IAmHQ,UAAU;IACV,gBAA0B;EvCmxPhC;EuCv4PF;IAsHQ,sBAAgC;EvCoxPtC;EuC14PF;IAmHQ,UAAU;IACV,gBAA0B;EvC0xPhC;EuC94PF;IAsHQ,sBAAgC;EvC2xPtC;EuCj5PF;IAmHQ,UAAU;IACV,UAA0B;EvCiyPhC;EuCr5PF;IAsHQ,gBAAgC;EvCkyPtC;EuCx5PF;IAmHQ,UAAU;IACV,gBAA0B;EvCwyPhC;EuC55PF;IAsHQ,sBAAgC;EvCyyPtC;EuC/5PF;IAmHQ,UAAU;IACV,gBAA0B;EvC+yPhC;EuCn6PF;IAsHQ,sBAAgC;EvCgzPtC;EuCt6PF;IAmHQ,UAAU;IACV,UAA0B;EvCszPhC;EuC16PF;IAsHQ,gBAAgC;EvCuzPtC;EuC76PF;IAmHQ,UAAU;IACV,gBAA0B;EvC6zPhC;EuCj7PF;IAsHQ,sBAAgC;EvC8zPtC;EuCp7PF;IAmHQ,UAAU;IACV,gBAA0B;EvCo0PhC;EuCx7PF;IAsHQ,sBAAgC;EvCq0PtC;EuC37PF;IAmHQ,UAAU;IACV,WAA0B;EvC20PhC;EuC/7PF;IAsHQ,iBAAgC;EvC40PtC;AACF;;ACh3PE;EsCnFF;IA0HM,UAAU;EvC80Pd;EuCx8PF;IA6HM,UAAU;IACV,WAAW;EvC80Pf;EuC58PF;IAiIM,UAAU;IACV,UAAU;EvC80Pd;EuCh9PF;IAqIM,UAAU;IACV,eAAe;EvC80PnB;EuCp9PF;IAyIM,UAAU;IACV,UAAU;EvC80Pd;EuCx9PF;IA6IM,UAAU;IACV,eAAe;EvC80PnB;EuC59PF;IAiJM,UAAU;IACV,UAAU;EvC80Pd;EuCh+PF;IAqJM,UAAU;IACV,UAAU;EvC80Pd;EuCp+PF;IAyJM,UAAU;IACV,UAAU;EvC80Pd;EuCx+PF;IA6JM,UAAU;IACV,UAAU;EvC80Pd;EuC5+PF;IAiKM,UAAU;IACV,UAAU;EvC80Pd;EuCh/PF;IAqKM,gBAAgB;EvC80PpB;EuCn/PF;IAwKM,qBAAqB;EvC80PzB;EuCt/PF;IA2KM,gBAAgB;EvC80PpB;EuCz/PF;IA8KM,qBAAqB;EvC80PzB;EuC5/PF;IAiLM,gBAAgB;EvC80PpB;EuC//PF;IAoLM,gBAAgB;EvC80PpB;EuClgQF;IAuLM,gBAAgB;EvC80PpB;EuCrgQF;IA0LM,gBAAgB;EvC80PpB;EuCxgQF;IA6LM,gBAAgB;EvC80PpB;EuC3gQF;IAiMQ,UAAU;IACV,SAA0B;EvC60PhC;EuC/gQF;IAqMQ,eAAgC;EvC60PtC;EuClhQF;IAiMQ,UAAU;IACV,eAA0B;EvCo1PhC;EuCthQF;IAqMQ,qBAAgC;EvCo1PtC;EuCzhQF;IAiMQ,UAAU;IACV,gBAA0B;EvC21PhC;EuC7hQF;IAqMQ,sBAAgC;EvC21PtC;EuChiQF;IAiMQ,UAAU;IACV,UAA0B;EvCk2PhC;EuCpiQF;IAqMQ,gBAAgC;EvCk2PtC;EuCviQF;IAiMQ,UAAU;IACV,gBAA0B;EvCy2PhC;EuC3iQF;IAqMQ,sBAAgC;EvCy2PtC;EuC9iQF;IAiMQ,UAAU;IACV,gBAA0B;EvCg3PhC;EuCljQF;IAqMQ,sBAAgC;EvCg3PtC;EuCrjQF;IAiMQ,UAAU;IACV,UAA0B;EvCu3PhC;EuCzjQF;IAqMQ,gBAAgC;EvCu3PtC;EuC5jQF;IAiMQ,UAAU;IACV,gBAA0B;EvC83PhC;EuChkQF;IAqMQ,sBAAgC;EvC83PtC;EuCnkQF;IAiMQ,UAAU;IACV,gBAA0B;EvCq4PhC;EuCvkQF;IAqMQ,sBAAgC;EvCq4PtC;EuC1kQF;IAiMQ,UAAU;IACV,UAA0B;EvC44PhC;EuC9kQF;IAqMQ,gBAAgC;EvC44PtC;EuCjlQF;IAiMQ,UAAU;IACV,gBAA0B;EvCm5PhC;EuCrlQF;IAqMQ,sBAAgC;EvCm5PtC;EuCxlQF;IAiMQ,UAAU;IACV,gBAA0B;EvC05PhC;EuC5lQF;IAqMQ,sBAAgC;EvC05PtC;EuC/lQF;IAiMQ,UAAU;IACV,WAA0B;EvCi6PhC;EuCnmQF;IAqMQ,iBAAgC;EvCi6PtC;AACF;;AC5gQE;EsC3FF;IAwMM,UAAU;EvCo6Pd;EuC5mQF;IA0MM,UAAU;IACV,WAAW;EvCq6Pf;EuChnQF;IA6MM,UAAU;IACV,UAAU;EvCs6Pd;EuCpnQF;IAgNM,UAAU;IACV,eAAe;EvCu6PnB;EuCxnQF;IAmNM,UAAU;IACV,UAAU;EvCw6Pd;EuC5nQF;IAsNM,UAAU;IACV,eAAe;EvCy6PnB;EuChoQF;IAyNM,UAAU;IACV,UAAU;EvC06Pd;EuCpoQF;IA4NM,UAAU;IACV,UAAU;EvC26Pd;EuCxoQF;IA+NM,UAAU;IACV,UAAU;EvC46Pd;EuC5oQF;IAkOM,UAAU;IACV,UAAU;EvC66Pd;EuChpQF;IAqOM,UAAU;IACV,UAAU;EvC86Pd;EuCppQF;IAwOM,gBAAgB;EvC+6PpB;EuCvpQF;IA0OM,qBAAqB;EvCg7PzB;EuC1pQF;IA4OM,gBAAgB;EvCi7PpB;EuC7pQF;IA8OM,qBAAqB;EvCk7PzB;EuChqQF;IAgPM,gBAAgB;EvCm7PpB;EuCnqQF;IAkPM,gBAAgB;EvCo7PpB;EuCtqQF;IAoPM,gBAAgB;EvCq7PpB;EuCzqQF;IAsPM,gBAAgB;EvCs7PpB;EuC5qQF;IAwPM,gBAAgB;EvCu7PpB;EuC/qQF;IA2PQ,UAAU;IACV,SAA0B;EvCu7PhC;EuCnrQF;IA8PQ,eAAgC;EvCw7PtC;EuCtrQF;IA2PQ,UAAU;IACV,eAA0B;EvC87PhC;EuC1rQF;IA8PQ,qBAAgC;EvC+7PtC;EuC7rQF;IA2PQ,UAAU;IACV,gBAA0B;EvCq8PhC;EuCjsQF;IA8PQ,sBAAgC;EvCs8PtC;EuCpsQF;IA2PQ,UAAU;IACV,UAA0B;EvC48PhC;EuCxsQF;IA8PQ,gBAAgC;EvC68PtC;EuC3sQF;IA2PQ,UAAU;IACV,gBAA0B;EvCm9PhC;EuC/sQF;IA8PQ,sBAAgC;EvCo9PtC;EuCltQF;IA2PQ,UAAU;IACV,gBAA0B;EvC09PhC;EuCttQF;IA8PQ,sBAAgC;EvC29PtC;EuCztQF;IA2PQ,UAAU;IACV,UAA0B;EvCi+PhC;EuC7tQF;IA8PQ,gBAAgC;EvCk+PtC;EuChuQF;IA2PQ,UAAU;IACV,gBAA0B;EvCw+PhC;EuCpuQF;IA8PQ,sBAAgC;EvCy+PtC;EuCvuQF;IA2PQ,UAAU;IACV,gBAA0B;EvC++PhC;EuC3uQF;IA8PQ,sBAAgC;EvCg/PtC;EuC9uQF;IA2PQ,UAAU;IACV,UAA0B;EvCs/PhC;EuClvQF;IA8PQ,gBAAgC;EvCu/PtC;EuCrvQF;IA2PQ,UAAU;IACV,gBAA0B;EvC6/PhC;EuCzvQF;IA8PQ,sBAAgC;EvC8/PtC;EuC5vQF;IA2PQ,UAAU;IACV,gBAA0B;EvCogQhC;EuChwQF;IA8PQ,sBAAgC;EvCqgQtC;EuCnwQF;IA2PQ,UAAU;IACV,WAA0B;EvC2gQhC;EuCvwQF;IA8PQ,iBAAgC;EvC4gQtC;AACF;;AC5qQE;EsC/FF;IAiQM,UAAU;EvC+gQd;EuChxQF;IAmQM,UAAU;IACV,WAAW;EvCghQf;EuCpxQF;IAsQM,UAAU;IACV,UAAU;EvCihQd;EuCxxQF;IAyQM,UAAU;IACV,eAAe;EvCkhQnB;EuC5xQF;IA4QM,UAAU;IACV,UAAU;EvCmhQd;EuChyQF;IA+QM,UAAU;IACV,eAAe;EvCohQnB;EuCpyQF;IAkRM,UAAU;IACV,UAAU;EvCqhQd;EuCxyQF;IAqRM,UAAU;IACV,UAAU;EvCshQd;EuC5yQF;IAwRM,UAAU;IACV,UAAU;EvCuhQd;EuChzQF;IA2RM,UAAU;IACV,UAAU;EvCwhQd;EuCpzQF;IA8RM,UAAU;IACV,UAAU;EvCyhQd;EuCxzQF;IAiSM,gBAAgB;EvC0hQpB;EuC3zQF;IAmSM,qBAAqB;EvC2hQzB;EuC9zQF;IAqSM,gBAAgB;EvC4hQpB;EuCj0QF;IAuSM,qBAAqB;EvC6hQzB;EuCp0QF;IAySM,gBAAgB;EvC8hQpB;EuCv0QF;IA2SM,gBAAgB;EvC+hQpB;EuC10QF;IA6SM,gBAAgB;EvCgiQpB;EuC70QF;IA+SM,gBAAgB;EvCiiQpB;EuCh1QF;IAiTM,gBAAgB;EvCkiQpB;EuCn1QF;IAoTQ,UAAU;IACV,SAA0B;EvCkiQhC;EuCv1QF;IAuTQ,eAAgC;EvCmiQtC;EuC11QF;IAoTQ,UAAU;IACV,eAA0B;EvCyiQhC;EuC91QF;IAuTQ,qBAAgC;EvC0iQtC;EuCj2QF;IAoTQ,UAAU;IACV,gBAA0B;EvCgjQhC;EuCr2QF;IAuTQ,sBAAgC;EvCijQtC;EuCx2QF;IAoTQ,UAAU;IACV,UAA0B;EvCujQhC;EuC52QF;IAuTQ,gBAAgC;EvCwjQtC;EuC/2QF;IAoTQ,UAAU;IACV,gBAA0B;EvC8jQhC;EuCn3QF;IAuTQ,sBAAgC;EvC+jQtC;EuCt3QF;IAoTQ,UAAU;IACV,gBAA0B;EvCqkQhC;EuC13QF;IAuTQ,sBAAgC;EvCskQtC;EuC73QF;IAoTQ,UAAU;IACV,UAA0B;EvC4kQhC;EuCj4QF;IAuTQ,gBAAgC;EvC6kQtC;EuCp4QF;IAoTQ,UAAU;IACV,gBAA0B;EvCmlQhC;EuCx4QF;IAuTQ,sBAAgC;EvColQtC;EuC34QF;IAoTQ,UAAU;IACV,gBAA0B;EvC0lQhC;EuC/4QF;IAuTQ,sBAAgC;EvC2lQtC;EuCl5QF;IAoTQ,UAAU;IACV,UAA0B;EvCimQhC;EuCt5QF;IAuTQ,gBAAgC;EvCkmQtC;EuCz5QF;IAoTQ,UAAU;IACV,gBAA0B;EvCwmQhC;EuC75QF;IAuTQ,sBAAgC;EvCymQtC;EuCh6QF;IAoTQ,UAAU;IACV,gBAA0B;EvC+mQhC;EuCp6QF;IAuTQ,sBAAgC;EvCgnQtC;EuCv6QF;IAoTQ,UAAU;IACV,WAA0B;EvCsnQhC;EuC36QF;IAuTQ,iBAAgC;EvCunQtC;AACF;;ACj0QI;EsC9GJ;IA0TM,UAAU;EvC0nQd;EuCp7QF;IA4TM,UAAU;IACV,WAAW;EvC2nQf;EuCx7QF;IA+TM,UAAU;IACV,UAAU;EvC4nQd;EuC57QF;IAkUM,UAAU;IACV,eAAe;EvC6nQnB;EuCh8QF;IAqUM,UAAU;IACV,UAAU;EvC8nQd;EuCp8QF;IAwUM,UAAU;IACV,eAAe;EvC+nQnB;EuCx8QF;IA2UM,UAAU;IACV,UAAU;EvCgoQd;EuC58QF;IA8UM,UAAU;IACV,UAAU;EvCioQd;EuCh9QF;IAiVM,UAAU;IACV,UAAU;EvCkoQd;EuCp9QF;IAoVM,UAAU;IACV,UAAU;EvCmoQd;EuCx9QF;IAuVM,UAAU;IACV,UAAU;EvCooQd;EuC59QF;IA0VM,gBAAgB;EvCqoQpB;EuC/9QF;IA4VM,qBAAqB;EvCsoQzB;EuCl+QF;IA8VM,gBAAgB;EvCuoQpB;EuCr+QF;IAgWM,qBAAqB;EvCwoQzB;EuCx+QF;IAkWM,gBAAgB;EvCyoQpB;EuC3+QF;IAoWM,gBAAgB;EvC0oQpB;EuC9+QF;IAsWM,gBAAgB;EvC2oQpB;EuCj/QF;IAwWM,gBAAgB;EvC4oQpB;EuCp/QF;IA0WM,gBAAgB;EvC6oQpB;EuCv/QF;IA6WQ,UAAU;IACV,SAA0B;EvC6oQhC;EuC3/QF;IAgXQ,eAAgC;EvC8oQtC;EuC9/QF;IA6WQ,UAAU;IACV,eAA0B;EvCopQhC;EuClgRF;IAgXQ,qBAAgC;EvCqpQtC;EuCrgRF;IA6WQ,UAAU;IACV,gBAA0B;EvC2pQhC;EuCzgRF;IAgXQ,sBAAgC;EvC4pQtC;EuC5gRF;IA6WQ,UAAU;IACV,UAA0B;EvCkqQhC;EuChhRF;IAgXQ,gBAAgC;EvCmqQtC;EuCnhRF;IA6WQ,UAAU;IACV,gBAA0B;EvCyqQhC;EuCvhRF;IAgXQ,sBAAgC;EvC0qQtC;EuC1hRF;IA6WQ,UAAU;IACV,gBAA0B;EvCgrQhC;EuC9hRF;IAgXQ,sBAAgC;EvCirQtC;EuCjiRF;IA6WQ,UAAU;IACV,UAA0B;EvCurQhC;EuCriRF;IAgXQ,gBAAgC;EvCwrQtC;EuCxiRF;IA6WQ,UAAU;IACV,gBAA0B;EvC8rQhC;EuC5iRF;IAgXQ,sBAAgC;EvC+rQtC;EuC/iRF;IA6WQ,UAAU;IACV,gBAA0B;EvCqsQhC;EuCnjRF;IAgXQ,sBAAgC;EvCssQtC;EuCtjRF;IA6WQ,UAAU;IACV,UAA0B;EvC4sQhC;EuC1jRF;IAgXQ,gBAAgC;EvC6sQtC;EuC7jRF;IA6WQ,UAAU;IACV,gBAA0B;EvCmtQhC;EuCjkRF;IAgXQ,sBAAgC;EvCotQtC;EuCpkRF;IA6WQ,UAAU;IACV,gBAA0B;EvC0tQhC;EuCxkRF;IAgXQ,sBAAgC;EvC2tQtC;EuC3kRF;IA6WQ,UAAU;IACV,WAA0B;EvCiuQhC;EuC/kRF;IAgXQ,iBAAgC;EvCkuQtC;AACF;;ACt9QI;EsC7HJ;IAmXM,UAAU;EvCquQd;EuCxlRF;IAqXM,UAAU;IACV,WAAW;EvCsuQf;EuC5lRF;IAwXM,UAAU;IACV,UAAU;EvCuuQd;EuChmRF;IA2XM,UAAU;IACV,eAAe;EvCwuQnB;EuCpmRF;IA8XM,UAAU;IACV,UAAU;EvCyuQd;EuCxmRF;IAiYM,UAAU;IACV,eAAe;EvC0uQnB;EuC5mRF;IAoYM,UAAU;IACV,UAAU;EvC2uQd;EuChnRF;IAuYM,UAAU;IACV,UAAU;EvC4uQd;EuCpnRF;IA0YM,UAAU;IACV,UAAU;EvC6uQd;EuCxnRF;IA6YM,UAAU;IACV,UAAU;EvC8uQd;EuC5nRF;IAgZM,UAAU;IACV,UAAU;EvC+uQd;EuChoRF;IAmZM,gBAAgB;EvCgvQpB;EuCnoRF;IAqZM,qBAAqB;EvCivQzB;EuCtoRF;IAuZM,gBAAgB;EvCkvQpB;EuCzoRF;IAyZM,qBAAqB;EvCmvQzB;EuC5oRF;IA2ZM,gBAAgB;EvCovQpB;EuC/oRF;IA6ZM,gBAAgB;EvCqvQpB;EuClpRF;IA+ZM,gBAAgB;EvCsvQpB;EuCrpRF;IAiaM,gBAAgB;EvCuvQpB;EuCxpRF;IAmaM,gBAAgB;EvCwvQpB;EuC3pRF;IAsaQ,UAAU;IACV,SAA0B;EvCwvQhC;EuC/pRF;IAyaQ,eAAgC;EvCyvQtC;EuClqRF;IAsaQ,UAAU;IACV,eAA0B;EvC+vQhC;EuCtqRF;IAyaQ,qBAAgC;EvCgwQtC;EuCzqRF;IAsaQ,UAAU;IACV,gBAA0B;EvCswQhC;EuC7qRF;IAyaQ,sBAAgC;EvCuwQtC;EuChrRF;IAsaQ,UAAU;IACV,UAA0B;EvC6wQhC;EuCprRF;IAyaQ,gBAAgC;EvC8wQtC;EuCvrRF;IAsaQ,UAAU;IACV,gBAA0B;EvCoxQhC;EuC3rRF;IAyaQ,sBAAgC;EvCqxQtC;EuC9rRF;IAsaQ,UAAU;IACV,gBAA0B;EvC2xQhC;EuClsRF;IAyaQ,sBAAgC;EvC4xQtC;EuCrsRF;IAsaQ,UAAU;IACV,UAA0B;EvCkyQhC;EuCzsRF;IAyaQ,gBAAgC;EvCmyQtC;EuC5sRF;IAsaQ,UAAU;IACV,gBAA0B;EvCyyQhC;EuChtRF;IAyaQ,sBAAgC;EvC0yQtC;EuCntRF;IAsaQ,UAAU;IACV,gBAA0B;EvCgzQhC;EuCvtRF;IAyaQ,sBAAgC;EvCizQtC;EuC1tRF;IAsaQ,UAAU;IACV,UAA0B;EvCuzQhC;EuC9tRF;IAyaQ,gBAAgC;EvCwzQtC;EuCjuRF;IAsaQ,UAAU;IACV,gBAA0B;EvC8zQhC;EuCruRF;IAyaQ,sBAAgC;EvC+zQtC;EuCxuRF;IAsaQ,UAAU;IACV,gBAA0B;EvCq0QhC;EuC5uRF;IAyaQ,sBAAgC;EvCs0QtC;EuC/uRF;IAsaQ,UAAU;IACV,WAA0B;EvC40QhC;EuCnvRF;IAyaQ,iBAAgC;EvC60QtC;AACF;;AuC50QA;EACE,qBA9akB;EA+alB,sBA/akB;EAgblB,oBAhbkB;AvC+vRpB;;AuCl1QA;EAKI,uBAlbgB;AvCmwRpB;;AuCt1QA;EAOI,qCAA4C;AvCm1QhD;;AuC11QA;EAUI,uBAAuB;AvCo1Q3B;;AuC91QA;EAYI,cAAc;EACd,eAAe;EACf,aAAa;AvCs1QjB;;AuCp2QA;EAgBM,SAAS;EACT,qBAAqB;AvCw1Q3B;;AuCz2QA;EAmBM,qBAAqB;AvC01Q3B;;AuC72QA;EAqBM,gBAAgB;AvC41QtB;;AuCj3QA;EAuBI,aAAa;AvC81QjB;;AuCr3QA;EAyBI,eAAe;AvCg2QnB;;AuCz3QA;EA2BI,mBAAmB;AvCk2QvB;;ACrtRE;EsCwVF;IA+BM,aAAa;EvCm2QjB;AACF;;AC/sRE;EsC4UF;IAmCM,aAAa;EvCq2QjB;AACF;;AuCn2QE;EACE,oBAAY;EACZ,wCAAwC;EACxC,yCAAyC;AvCs2Q7C;;AuCz2QE;EAKI,8BAA8B;EAC9B,+BAA+B;AvCw2QrC;;AuC92QE;EASM,iBAAY;AvCy2QpB;;ACpvRE;EsCkYA;IAYQ,iBAAY;EvC22QpB;AACF;;ACtvRE;EsC8XA;IAeQ,iBAAY;EvC82QpB;AACF;;ACxvRE;EsC0XA;IAkBQ,iBAAY;EvCi3QpB;AACF;;AC1vRE;EsCsXA;IAqBQ,iBAAY;EvCo3QpB;AACF;;AC5vRE;EsCkXA;IAwBQ,iBAAY;EvCu3QpB;AACF;;AC7vRI;EsC6WF;IA2BQ,iBAAY;EvC03QpB;AACF;;ACzvRI;EsCmWF;IA8BQ,iBAAY;EvC63QpB;AACF;;AC1vRI;EsC8VF;IAiCQ,iBAAY;EvCg4QpB;AACF;;ACtvRI;EsCoVF;IAoCQ,iBAAY;EvCm4QpB;AACF;;AuCx6QE;EASM,oBAAY;AvCm6QpB;;AC9yRE;EsCkYA;IAYQ,oBAAY;EvCq6QpB;AACF;;AChzRE;EsC8XA;IAeQ,oBAAY;EvCw6QpB;AACF;;AClzRE;EsC0XA;IAkBQ,oBAAY;EvC26QpB;AACF;;ACpzRE;EsCsXA;IAqBQ,oBAAY;EvC86QpB;AACF;;ACtzRE;EsCkXA;IAwBQ,oBAAY;EvCi7QpB;AACF;;ACvzRI;EsC6WF;IA2BQ,oBAAY;EvCo7QpB;AACF;;ACnzRI;EsCmWF;IA8BQ,oBAAY;EvCu7QpB;AACF;;ACpzRI;EsC8VF;IAiCQ,oBAAY;EvC07QpB;AACF;;AChzRI;EsCoVF;IAoCQ,oBAAY;EvC67QpB;AACF;;AuCl+QE;EASM,mBAAY;AvC69QpB;;ACx2RE;EsCkYA;IAYQ,mBAAY;EvC+9QpB;AACF;;AC12RE;EsC8XA;IAeQ,mBAAY;EvCk+QpB;AACF;;AC52RE;EsC0XA;IAkBQ,mBAAY;EvCq+QpB;AACF;;AC92RE;EsCsXA;IAqBQ,mBAAY;EvCw+QpB;AACF;;ACh3RE;EsCkXA;IAwBQ,mBAAY;EvC2+QpB;AACF;;ACj3RI;EsC6WF;IA2BQ,mBAAY;EvC8+QpB;AACF;;AC72RI;EsCmWF;IA8BQ,mBAAY;EvCi/QpB;AACF;;AC92RI;EsC8VF;IAiCQ,mBAAY;EvCo/QpB;AACF;;AC12RI;EsCoVF;IAoCQ,mBAAY;EvCu/QpB;AACF;;AuC5hRE;EASM,oBAAY;AvCuhRpB;;ACl6RE;EsCkYA;IAYQ,oBAAY;EvCyhRpB;AACF;;ACp6RE;EsC8XA;IAeQ,oBAAY;EvC4hRpB;AACF;;ACt6RE;EsC0XA;IAkBQ,oBAAY;EvC+hRpB;AACF;;ACx6RE;EsCsXA;IAqBQ,oBAAY;EvCkiRpB;AACF;;AC16RE;EsCkXA;IAwBQ,oBAAY;EvCqiRpB;AACF;;AC36RI;EsC6WF;IA2BQ,oBAAY;EvCwiRpB;AACF;;ACv6RI;EsCmWF;IA8BQ,oBAAY;EvC2iRpB;AACF;;ACx6RI;EsC8VF;IAiCQ,oBAAY;EvC8iRpB;AACF;;ACp6RI;EsCoVF;IAoCQ,oBAAY;EvCijRpB;AACF;;AuCtlRE;EASM,iBAAY;AvCilRpB;;AC59RE;EsCkYA;IAYQ,iBAAY;EvCmlRpB;AACF;;AC99RE;EsC8XA;IAeQ,iBAAY;EvCslRpB;AACF;;ACh+RE;EsC0XA;IAkBQ,iBAAY;EvCylRpB;AACF;;ACl+RE;EsCsXA;IAqBQ,iBAAY;EvC4lRpB;AACF;;ACp+RE;EsCkXA;IAwBQ,iBAAY;EvC+lRpB;AACF;;ACr+RI;EsC6WF;IA2BQ,iBAAY;EvCkmRpB;AACF;;ACj+RI;EsCmWF;IA8BQ,iBAAY;EvCqmRpB;AACF;;ACl+RI;EsC8VF;IAiCQ,iBAAY;EvCwmRpB;AACF;;AC99RI;EsCoVF;IAoCQ,iBAAY;EvC2mRpB;AACF;;AuChpRE;EASM,oBAAY;AvC2oRpB;;ACthSE;EsCkYA;IAYQ,oBAAY;EvC6oRpB;AACF;;ACxhSE;EsC8XA;IAeQ,oBAAY;EvCgpRpB;AACF;;AC1hSE;EsC0XA;IAkBQ,oBAAY;EvCmpRpB;AACF;;AC5hSE;EsCsXA;IAqBQ,oBAAY;EvCspRpB;AACF;;AC9hSE;EsCkXA;IAwBQ,oBAAY;EvCypRpB;AACF;;AC/hSI;EsC6WF;IA2BQ,oBAAY;EvC4pRpB;AACF;;AC3hSI;EsCmWF;IA8BQ,oBAAY;EvC+pRpB;AACF;;AC5hSI;EsC8VF;IAiCQ,oBAAY;EvCkqRpB;AACF;;ACxhSI;EsCoVF;IAoCQ,oBAAY;EvCqqRpB;AACF;;AuC1sRE;EASM,mBAAY;AvCqsRpB;;AChlSE;EsCkYA;IAYQ,mBAAY;EvCusRpB;AACF;;ACllSE;EsC8XA;IAeQ,mBAAY;EvC0sRpB;AACF;;ACplSE;EsC0XA;IAkBQ,mBAAY;EvC6sRpB;AACF;;ACtlSE;EsCsXA;IAqBQ,mBAAY;EvCgtRpB;AACF;;ACxlSE;EsCkXA;IAwBQ,mBAAY;EvCmtRpB;AACF;;ACzlSI;EsC6WF;IA2BQ,mBAAY;EvCstRpB;AACF;;ACrlSI;EsCmWF;IA8BQ,mBAAY;EvCytRpB;AACF;;ACtlSI;EsC8VF;IAiCQ,mBAAY;EvC4tRpB;AACF;;ACllSI;EsCoVF;IAoCQ,mBAAY;EvC+tRpB;AACF;;AuCpwRE;EASM,oBAAY;AvC+vRpB;;AC1oSE;EsCkYA;IAYQ,oBAAY;EvCiwRpB;AACF;;AC5oSE;EsC8XA;IAeQ,oBAAY;EvCowRpB;AACF;;AC9oSE;EsC0XA;IAkBQ,oBAAY;EvCuwRpB;AACF;;AChpSE;EsCsXA;IAqBQ,oBAAY;EvC0wRpB;AACF;;AClpSE;EsCkXA;IAwBQ,oBAAY;EvC6wRpB;AACF;;ACnpSI;EsC6WF;IA2BQ,oBAAY;EvCgxRpB;AACF;;AC/oSI;EsCmWF;IA8BQ,oBAAY;EvCmxRpB;AACF;;AChpSI;EsC8VF;IAiCQ,oBAAY;EvCsxRpB;AACF;;AC5oSI;EsCoVF;IAoCQ,oBAAY;EvCyxRpB;AACF;;AuC9zRE;EASM,iBAAY;AvCyzRpB;;ACpsSE;EsCkYA;IAYQ,iBAAY;EvC2zRpB;AACF;;ACtsSE;EsC8XA;IAeQ,iBAAY;EvC8zRpB;AACF;;ACxsSE;EsC0XA;IAkBQ,iBAAY;EvCi0RpB;AACF;;AC1sSE;EsCsXA;IAqBQ,iBAAY;EvCo0RpB;AACF;;AC5sSE;EsCkXA;IAwBQ,iBAAY;EvCu0RpB;AACF;;AC7sSI;EsC6WF;IA2BQ,iBAAY;EvC00RpB;AACF;;ACzsSI;EsCmWF;IA8BQ,iBAAY;EvC60RpB;AACF;;AC1sSI;EsC8VF;IAiCQ,iBAAY;EvCg1RpB;AACF;;ACtsSI;EsCoVF;IAoCQ,iBAAY;EvCm1RpB;AACF;;AwCz0SA;EACE,oBAAoB;EACpB,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,+BAAuB;EAAvB,4BAAuB;EAAvB,uBAAuB;AxC40SzB;;AwCl1SA;EASI,qBAA+B;EAC/B,sBAAgC;EAChC,oBAA8B;AxC60SlC;;AwCx1SA;EAaM,uBAAiC;AxC+0SvC;;AwC51SA;EAeM,sBAjBgB;AxCk2StB;;AwCh2SA;EAiBI,oBAAoB;AxCm1SxB;;AwCp2SA;EAmBI,gBArBkB;AxC02StB;;AwCx2SA;EAqBI,sBAAsB;AxCu1S1B;;AwC52SA;EAuBM,gCAAgC;AxCy1StC;;AC7xSE;EuCnFF;IA2BM,aAAa;ExC01SjB;EwCr3SF;IA8BQ,UAAU;IACV,eAAuB;ExC01S7B;EwCz3SF;IA8BQ,UAAU;IACV,gBAAuB;ExC81S7B;EwC73SF;IA8BQ,UAAU;IACV,UAAuB;ExCk2S7B;EwCj4SF;IA8BQ,UAAU;IACV,gBAAuB;ExCs2S7B;EwCr4SF;IA8BQ,UAAU;IACV,gBAAuB;ExC02S7B;EwCz4SF;IA8BQ,UAAU;IACV,UAAuB;ExC82S7B;EwC74SF;IA8BQ,UAAU;IACV,gBAAuB;ExCk3S7B;EwCj5SF;IA8BQ,UAAU;IACV,gBAAuB;ExCs3S7B;EwCr5SF;IA8BQ,UAAU;IACV,UAAuB;ExC03S7B;EwCz5SF;IA8BQ,UAAU;IACV,gBAAuB;ExC83S7B;EwC75SF;IA8BQ,UAAU;IACV,gBAAuB;ExCk4S7B;EwCj6SF;IA8BQ,UAAU;IACV,WAAuB;ExCs4S7B;AACF;;AyCt6SA;EACE,oBAAoB;EACpB,aAAa;EACb,sBAAsB;EACtB,8BAA8B;AzCy6ShC;;AyC76SA;EAMI,gBAAgB;AzC26SpB;;AyCj7SA;EASM,mBAAmB;AzC46SzB;;AyCr7SA;EAeM,uBvCHyB;EuCIzB,cvChBuB;AF07S7B;;AyC17SA;;EAmBQ,cAAc;AzC46StB;;AyC/7SA;EAqBQ,cvCrBqB;AFm8S7B;;AyCn8SA;EAuBQ,4BvCvBqB;AFu8S7B;;AyCv8SA;;EA0BU,cvC1BmB;AF48S7B;;ACj3SE;EwC3FF;IA6BU,uBvCjBqB;EFq8S7B;AACF;;AyCl9SA;;EAgCQ,4BvChCqB;AFu9S7B;;AyCv9SA;;;EAqCU,yBAAoC;EACpC,cvCtCmB;AF89S7B;;AyC99SA;EAyCU,cvCzCmB;EuC0CnB,YAAY;AzCy7StB;;AyCn+SA;EA4CY,UAAU;AzC27StB;;AyCv+SA;EA+CY,UAAU;AzC47StB;;AyC3+SA;EAmDY,cvCnDiB;AF++S7B;;AyC/+SA;EAqDc,uCvCrDe;AFm/S7B;;AyCn/SA;EAyDc,yBvCzDe;EuC0Df,qBvC1De;EuC2Df,YvC/CiB;AF6+S/B;;AyCz/SA;EAgEQ,4EAAyG;AzC67SjH;;AC96SE;EwC/EF;IAmEY,4EAAyG;EzC+7SnH;AACF;;AyCngTA;EAeM,yBvCfuB;EuCgBvB,YvCJyB;AF4/S/B;;AyCxgTA;;EAmBQ,cAAc;AzC0/StB;;AyC7gTA;EAqBQ,YvCTuB;AFqgT/B;;AyCjhTA;EAuBQ,+BvCXuB;AFygT/B;;AyCrhTA;;EA0BU,YvCdqB;AF8gT/B;;AC/7SE;EwC3FF;IA6BU,yBvC7BmB;EF+hT3B;AACF;;AyChiTA;;EAgCQ,+BvCpBuB;AFyhT/B;;AyCriTA;;;EAqCU,uBAAoC;EACpC,YvC1BqB;AFgiT/B;;AyC5iTA;EAyCU,YvC7BqB;EuC8BrB,YAAY;AzCugTtB;;AyCjjTA;EA4CY,UAAU;AzCygTtB;;AyCrjTA;EA+CY,UAAU;AzC0gTtB;;AyCzjTA;EAmDY,YvCvCmB;AFijT/B;;AyC7jTA;EAqDc,uCvCrDe;AFikT7B;;AyCjkTA;EAyDc,uBvC7CiB;EuC8CjB,mBvC9CiB;EuC+CjB,cvC3De;AFukT7B;;AyCvkTA;EAgEQ,8EAAyG;AzC2gTjH;;AC5/SE;EwC/EF;IAmEY,8EAAyG;EzC6gTnH;AACF;;AyCjlTA;EAeM,4BvCLwB;EuCMxB,cvCZwB;AFklT9B;;AyCtlTA;;EAmBQ,cAAc;AzCwkTtB;;AyC3lTA;EAqBQ,cvCjBsB;AF2lT9B;;AyC/lTA;EAuBQ,4BvCnBsB;AF+lT9B;;AyCnmTA;;EA0BU,cvCtBoB;AFomT9B;;AC7gTE;EwC3FF;IA6BU,4BvCnBoB;EFmmT5B;AACF;;AyC9mTA;;EAgCQ,4BvC5BsB;AF+mT9B;;AyCnnTA;;;EAqCU,yBAAoC;EACpC,cvClCoB;AFsnT9B;;AyC1nTA;EAyCU,cvCrCoB;EuCsCpB,YAAY;AzCqlTtB;;AyC/nTA;EA4CY,UAAU;AzCulTtB;;AyCnoTA;EA+CY,UAAU;AzCwlTtB;;AyCvoTA;EAmDY,cvC/CkB;AFuoT9B;;AyC3oTA;EAqDc,uCvCrDe;AF+oT7B;;AyC/oTA;EAyDc,yBvCrDgB;EuCsDhB,qBvCtDgB;EuCuDhB,iBvCjDgB;AF2oT9B;;AyCrpTA;EAgEQ,iFAAyG;AzCylTjH;;AC1kTE;EwC/EF;IAmEY,iFAAyG;EzC2lTnH;AACF;;AyC/pTA;EAeM,yBvCXwB;EuCYxB,iBvCNwB;AF0pT9B;;AyCpqTA;;EAmBQ,cAAc;AzCspTtB;;AyCzqTA;EAqBQ,iBvCXsB;AFmqT9B;;AyC7qTA;EAuBQ,+BvCbsB;AFuqT9B;;AyCjrTA;;EA0BU,iBvChBoB;AF4qT9B;;AC3lTE;EwC3FF;IA6BU,yBvCzBoB;EFurT5B;AACF;;AyC5rTA;;EAgCQ,+BvCtBsB;AFurT9B;;AyCjsTA;;;EAqCU,yBAAoC;EACpC,iBvC5BoB;AF8rT9B;;AyCxsTA;EAyCU,iBvC/BoB;EuCgCpB,YAAY;AzCmqTtB;;AyC7sTA;EA4CY,UAAU;AzCqqTtB;;AyCjtTA;EA+CY,UAAU;AzCsqTtB;;AyCrtTA;EAmDY,iBvCzCkB;AF+sT9B;;AyCztTA;EAqDc,uCvCrDe;AF6tT7B;;AyC7tTA;EAyDc,4BvC/CgB;EuCgDhB,wBvChDgB;EuCiDhB,cvCvDgB;AF+tT9B;;AyCnuTA;EAgEQ,gFAAyG;AzCuqTjH;;ACxpTE;EwC/EF;IAmEY,gFAAyG;EzCyqTnH;AACF;;AyC7uTA;EAeM,yBvCE4B;EuCD5B,WhC2CU;ATurThB;;AyClvTA;;EAmBQ,cAAc;AzCouTtB;;AyCvvTA;EAqBQ,WhCsCQ;ATgsThB;;AyC3vTA;EAuBQ,+BhCoCQ;ATosThB;;AyC/vTA;;EA0BU,WhCiCM;ATysThB;;ACzqTE;EwC3FF;IA6BU,yBvCZwB;EFwvThC;AACF;;AyC1wTA;;EAgCQ,+BhC2BQ;ATotThB;;AyC/wTA;;;EAqCU,yBAAoC;EACpC,WhCqBM;AT2tThB;;AyCtxTA;EAyCU,WhCkBM;EgCjBN,YAAY;AzCivTtB;;AyC3xTA;EA4CY,UAAU;AzCmvTtB;;AyC/xTA;EA+CY,UAAU;AzCovTtB;;AyCnyTA;EAmDY,WhCQI;AT4uThB;;AyCvyTA;EAqDc,uCvCrDe;AF2yT7B;;AyC3yTA;EAyDc,sBhCEE;EgCDF,kBhCCE;EgCAF,cvC1CoB;AFgyTlC;;AyCjzTA;EAgEQ,gFAAyG;AzCqvTjH;;ACtuTE;EwC/EF;IAmEY,gFAAyG;EzCuvTnH;AACF;;AyC3zTA;EAeM,yBvCI4B;EuCH5B,WhC2CU;ATqwThB;;AyCh0TA;;EAmBQ,cAAc;AzCkzTtB;;AyCr0TA;EAqBQ,WhCsCQ;AT8wThB;;AyCz0TA;EAuBQ,+BhCoCQ;ATkxThB;;AyC70TA;;EA0BU,WhCiCM;ATuxThB;;ACvvTE;EwC3FF;IA6BU,yBvCVwB;EFo0ThC;AACF;;AyCx1TA;;EAgCQ,+BhC2BQ;ATkyThB;;AyC71TA;;;EAqCU,yBAAoC;EACpC,WhCqBM;ATyyThB;;AyCp2TA;EAyCU,WhCkBM;EgCjBN,YAAY;AzC+zTtB;;AyCz2TA;EA4CY,UAAU;AzCi0TtB;;AyC72TA;EA+CY,UAAU;AzCk0TtB;;AyCj3TA;EAmDY,WhCQI;AT0zThB;;AyCr3TA;EAqDc,uCvCrDe;AFy3T7B;;AyCz3TA;EAyDc,sBhCEE;EgCDF,kBhCCE;EgCAF,cvCxCoB;AF42TlC;;AyC/3TA;EAgEQ,gFAAyG;AzCm0TjH;;ACpzTE;EwC/EF;IAmEY,gFAAyG;EzCq0TnH;AACF;;AyCz4TA;EAeM,yBvCG4B;EuCF5B,WhC2CU;ATm1ThB;;AyC94TA;;EAmBQ,cAAc;AzCg4TtB;;AyCn5TA;EAqBQ,WhCsCQ;AT41ThB;;AyCv5TA;EAuBQ,+BhCoCQ;ATg2ThB;;AyC35TA;;EA0BU,WhCiCM;ATq2ThB;;ACr0TE;EwC3FF;IA6BU,yBvCXwB;EFm5ThC;AACF;;AyCt6TA;;EAgCQ,+BhC2BQ;ATg3ThB;;AyC36TA;;;EAqCU,yBAAoC;EACpC,WhCqBM;ATu3ThB;;AyCl7TA;EAyCU,WhCkBM;EgCjBN,YAAY;AzC64TtB;;AyCv7TA;EA4CY,UAAU;AzC+4TtB;;AyC37TA;EA+CY,UAAU;AzCg5TtB;;AyC/7TA;EAmDY,WhCQI;ATw4ThB;;AyCn8TA;EAqDc,uCvCrDe;AFu8T7B;;AyCv8TA;EAyDc,sBhCEE;EgCDF,kBhCCE;EgCAF,cvCzCoB;AF27TlC;;AyC78TA;EAgEQ,gFAAyG;AzCi5TjH;;ACl4TE;EwC/EF;IAmEY,gFAAyG;EzCm5TnH;AACF;;AyCv9TA;EAeM,yBvCC4B;EuCA5B,WhC2CU;ATi6ThB;;AyC59TA;;EAmBQ,cAAc;AzC88TtB;;AyCj+TA;EAqBQ,WhCsCQ;AT06ThB;;AyCr+TA;EAuBQ,+BhCoCQ;AT86ThB;;AyCz+TA;;EA0BU,WhCiCM;ATm7ThB;;ACn5TE;EwC3FF;IA6BU,yBvCbwB;EFm+ThC;AACF;;AyCp/TA;;EAgCQ,+BhC2BQ;AT87ThB;;AyCz/TA;;;EAqCU,yBAAoC;EACpC,WhCqBM;ATq8ThB;;AyChgUA;EAyCU,WhCkBM;EgCjBN,YAAY;AzC29TtB;;AyCrgUA;EA4CY,UAAU;AzC69TtB;;AyCzgUA;EA+CY,UAAU;AzC89TtB;;AyC7gUA;EAmDY,WhCQI;ATs9ThB;;AyCjhUA;EAqDc,uCvCrDe;AFqhU7B;;AyCrhUA;EAyDc,sBhCEE;EgCDF,kBhCCE;EgCAF,cvC3CoB;AF2gUlC;;AyC3hUA;EAgEQ,gFAAyG;AzC+9TjH;;ACh9TE;EwC/EF;IAmEY,gFAAyG;EzCi+TnH;AACF;;AyCriUA;EAeM,yBvCA4B;EuCC5B,yBhCyCe;ATi/TrB;;AyC1iUA;;EAmBQ,cAAc;AzC4hUtB;;AyC/iUA;EAqBQ,yBhCoCa;AT0/TrB;;AyCnjUA;EAuBQ,yBhCkCa;AT8/TrB;;AyCvjUA;;EA0BU,yBhC+BW;ATmgUrB;;ACj+TE;EwC3FF;IA6BU,yBvCdwB;EFkjUhC;AACF;;AyClkUA;;EAgCQ,yBhCyBa;AT8gUrB;;AyCvkUA;;;EAqCU,yBAAoC;EACpC,yBhCmBW;ATqhUrB;;AyC9kUA;EAyCU,yBhCgBW;EgCfX,YAAY;AzCyiUtB;;AyCnlUA;EA4CY,UAAU;AzC2iUtB;;AyCvlUA;EA+CY,UAAU;AzC4iUtB;;AyC3lUA;EAmDY,yBhCMS;ATsiUrB;;AyC/lUA;EAqDc,uCvCrDe;AFmmU7B;;AyCnmUA;EAyDc,oChCAO;EgCCP,gChCDO;EgCEP,cvC5CoB;AF0lUlC;;AyCzmUA;EAgEQ,gFAAyG;AzC6iUjH;;AC9hUE;EwC/EF;IAmEY,gFAAyG;EzC+iUnH;AACF;;AyCnnUA;EAeM,yBvCM4B;EuCL5B,WhC2CU;AT6jUhB;;AyCxnUA;;EAmBQ,cAAc;AzC0mUtB;;AyC7nUA;EAqBQ,WhCsCQ;ATskUhB;;AyCjoUA;EAuBQ,+BhCoCQ;AT0kUhB;;AyCroUA;;EA0BU,WhCiCM;AT+kUhB;;AC/iUE;EwC3FF;IA6BU,yBvCRwB;EF0nUhC;AACF;;AyChpUA;;EAgCQ,+BhC2BQ;AT0lUhB;;AyCrpUA;;;EAqCU,yBAAoC;EACpC,WhCqBM;ATimUhB;;AyC5pUA;EAyCU,WhCkBM;EgCjBN,YAAY;AzCunUtB;;AyCjqUA;EA4CY,UAAU;AzCynUtB;;AyCrqUA;EA+CY,UAAU;AzC0nUtB;;AyCzqUA;EAmDY,WhCQI;ATknUhB;;AyC7qUA;EAqDc,uCvCrDe;AFirU7B;;AyCjrUA;EAyDc,sBhCEE;EgCDF,kBhCCE;EgCAF,cvCtCoB;AFkqUlC;;AyCvrUA;EAgEQ,gFAAyG;AzC2nUjH;;AC5mUE;EwC/EF;IAmEY,gFAAyG;EzC6nUnH;AACF;;AyCjsUA;EAuEM,sBAAsB;EACtB,mBAAmB;AzC8nUzB;;ACnnUE;EwCnFF;IA4EQ,oBAAoB;IACpB,iBAAiB;EzC+nUvB;AACF;;AC1nUE;EwCnFF;IAiFQ,qBAAqB;IACrB,kBAAkB;EzCioUxB;AACF;;AyCptUA;EAuFM,mBAAmB;EACnB,aAAa;AzCioUnB;;AyCztUA;EA0FQ,YAAY;EACZ,cAAc;AzCmoUtB;;AyC9tUA;EA6FI,gBAAgB;AzCqoUpB;;AyCluUA;EA+FI,iBAAiB;AzCuoUrB;;AyCnoUA;EAEE,gBAAgB;AzCqoUlB;;AyCvoUA;EAII,SAAS;EACT,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,QAAQ;EACR,6CAAqC;UAArC,qCAAqC;AzCuoUzC;;AyChpUA;EAYI,YAAY;AzCwoUhB;;ACxqUE;EwCoBF;IAeI,aAAa;EzC0oUf;AACF;;AyCzoUA;EACE,kBAAkB;AzC4oUpB;;AClrUE;EwCqCF;IAKM,aAAa;EzC6oUjB;EyClpUF;IAOQ,sBAAsB;EzC8oU5B;AACF;;ACvrUE;EwCiCF;IASI,aAAa;IACb,uBAAuB;EzCkpUzB;EyC5pUF;IAYM,oBAAoB;EzCmpUxB;AACF;;AyChpUA;;EAEE,YAAY;EACZ,cAAc;AzCmpUhB;;AyCjpUA;EACE,YAAY;EACZ,cAAc;EACd,oBAAoB;AzCopUtB;;A0C9xUA;EACE,oBAL2B;A1CsyU7B;;ACrsUE;EyC7FF;IAMM,oBAT8B;E1C0yUlC;E0CvyUF;IAQM,qBAV8B;E1C4yUlC;AACF;;A2C3yUA;EACE,yBzCQ4B;EyCP5B,yBAJ+B;A3CkzUjC","file":"bulma.css"} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.min.css b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.min.css new file mode 100644 index 00000000000..434a97896ad --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/bulma-0.7.5/bulma.min.css @@ -0,0 +1 @@ +/*! bulma.io v0.7.5 | MIT License | github.com/jgthms/bulma */@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.breadcrumb,.button,.delete,.file,.is-unselectable,.modal-close,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:center;transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.highlight:not(:last-child),.level:not(:last-child),.list:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.25em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.375em - 1px);padding-left:calc(.625em - 1px);padding-right:calc(.625em - 1px);padding-top:calc(.375em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}embed,iframe,img,object,video{height:auto;max-width:100%}audio{max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:left}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1em;font-weight:400;line-height:1.5}a{color:#3273dc;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#ff3860;font-size:.875em;font-weight:400;padding:.25em .5em .25em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type=checkbox],input[type=radio]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:left}table th{color:#363636}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left!important}.is-pulled-right{float:right!important}.is-clipped{overflow:hidden!important}.is-size-1{font-size:3rem!important}.is-size-2{font-size:2.5rem!important}.is-size-3{font-size:2rem!important}.is-size-4{font-size:1.5rem!important}.is-size-5{font-size:1.25rem!important}.is-size-6{font-size:1rem!important}.is-size-7{font-size:.75rem!important}@media screen and (max-width:768px){.is-size-1-mobile{font-size:3rem!important}.is-size-2-mobile{font-size:2.5rem!important}.is-size-3-mobile{font-size:2rem!important}.is-size-4-mobile{font-size:1.5rem!important}.is-size-5-mobile{font-size:1.25rem!important}.is-size-6-mobile{font-size:1rem!important}.is-size-7-mobile{font-size:.75rem!important}}@media screen and (min-width:769px),print{.is-size-1-tablet{font-size:3rem!important}.is-size-2-tablet{font-size:2.5rem!important}.is-size-3-tablet{font-size:2rem!important}.is-size-4-tablet{font-size:1.5rem!important}.is-size-5-tablet{font-size:1.25rem!important}.is-size-6-tablet{font-size:1rem!important}.is-size-7-tablet{font-size:.75rem!important}}@media screen and (max-width:1023px){.is-size-1-touch{font-size:3rem!important}.is-size-2-touch{font-size:2.5rem!important}.is-size-3-touch{font-size:2rem!important}.is-size-4-touch{font-size:1.5rem!important}.is-size-5-touch{font-size:1.25rem!important}.is-size-6-touch{font-size:1rem!important}.is-size-7-touch{font-size:.75rem!important}}@media screen and (min-width:1024px){.is-size-1-desktop{font-size:3rem!important}.is-size-2-desktop{font-size:2.5rem!important}.is-size-3-desktop{font-size:2rem!important}.is-size-4-desktop{font-size:1.5rem!important}.is-size-5-desktop{font-size:1.25rem!important}.is-size-6-desktop{font-size:1rem!important}.is-size-7-desktop{font-size:.75rem!important}}@media screen and (min-width:1216px){.is-size-1-widescreen{font-size:3rem!important}.is-size-2-widescreen{font-size:2.5rem!important}.is-size-3-widescreen{font-size:2rem!important}.is-size-4-widescreen{font-size:1.5rem!important}.is-size-5-widescreen{font-size:1.25rem!important}.is-size-6-widescreen{font-size:1rem!important}.is-size-7-widescreen{font-size:.75rem!important}}@media screen and (min-width:1408px){.is-size-1-fullhd{font-size:3rem!important}.is-size-2-fullhd{font-size:2.5rem!important}.is-size-3-fullhd{font-size:2rem!important}.is-size-4-fullhd{font-size:1.5rem!important}.is-size-5-fullhd{font-size:1.25rem!important}.is-size-6-fullhd{font-size:1rem!important}.is-size-7-fullhd{font-size:.75rem!important}}.has-text-centered{text-align:center!important}.has-text-justified{text-align:justify!important}.has-text-left{text-align:left!important}.has-text-right{text-align:right!important}@media screen and (max-width:768px){.has-text-centered-mobile{text-align:center!important}}@media screen and (min-width:769px),print{.has-text-centered-tablet{text-align:center!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1023px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1024px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-centered-desktop-only{text-align:center!important}}@media screen and (min-width:1216px){.has-text-centered-widescreen{text-align:center!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-centered-widescreen-only{text-align:center!important}}@media screen and (min-width:1408px){.has-text-centered-fullhd{text-align:center!important}}@media screen and (max-width:768px){.has-text-justified-mobile{text-align:justify!important}}@media screen and (min-width:769px),print{.has-text-justified-tablet{text-align:justify!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1023px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1024px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-justified-desktop-only{text-align:justify!important}}@media screen and (min-width:1216px){.has-text-justified-widescreen{text-align:justify!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-justified-widescreen-only{text-align:justify!important}}@media screen and (min-width:1408px){.has-text-justified-fullhd{text-align:justify!important}}@media screen and (max-width:768px){.has-text-left-mobile{text-align:left!important}}@media screen and (min-width:769px),print{.has-text-left-tablet{text-align:left!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1023px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1024px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-left-desktop-only{text-align:left!important}}@media screen and (min-width:1216px){.has-text-left-widescreen{text-align:left!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-left-widescreen-only{text-align:left!important}}@media screen and (min-width:1408px){.has-text-left-fullhd{text-align:left!important}}@media screen and (max-width:768px){.has-text-right-mobile{text-align:right!important}}@media screen and (min-width:769px),print{.has-text-right-tablet{text-align:right!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1023px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1024px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-right-desktop-only{text-align:right!important}}@media screen and (min-width:1216px){.has-text-right-widescreen{text-align:right!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-right-widescreen-only{text-align:right!important}}@media screen and (min-width:1408px){.has-text-right-fullhd{text-align:right!important}}.is-capitalized{text-transform:capitalize!important}.is-lowercase{text-transform:lowercase!important}.is-uppercase{text-transform:uppercase!important}.is-italic{font-style:italic!important}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-link{color:#3273dc!important}a.has-text-link:focus,a.has-text-link:hover{color:#205bbc!important}.has-background-link{background-color:#3273dc!important}.has-text-info{color:#209cee!important}a.has-text-info:focus,a.has-text-info:hover{color:#0f81cc!important}.has-background-info{background-color:#209cee!important}.has-text-success{color:#23d160!important}a.has-text-success:focus,a.has-text-success:hover{color:#1ca64c!important}.has-background-success{background-color:#23d160!important}.has-text-warning{color:#ffdd57!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd324!important}.has-background-warning{background-color:#ffdd57!important}.has-text-danger{color:#ff3860!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ff0537!important}.has-background-danger{background-color:#ff3860!important}.has-text-black-bis{color:#121212!important}.has-background-black-bis{background-color:#121212!important}.has-text-black-ter{color:#242424!important}.has-background-black-ter{background-color:#242424!important}.has-text-grey-darker{color:#363636!important}.has-background-grey-darker{background-color:#363636!important}.has-text-grey-dark{color:#4a4a4a!important}.has-background-grey-dark{background-color:#4a4a4a!important}.has-text-grey{color:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!important}.has-text-grey-light{color:#b5b5b5!important}.has-background-grey-light{background-color:#b5b5b5!important}.has-text-grey-lighter{color:#dbdbdb!important}.has-background-grey-lighter{background-color:#dbdbdb!important}.has-text-white-ter{color:#f5f5f5!important}.has-background-white-ter{background-color:#f5f5f5!important}.has-text-white-bis{color:#fafafa!important}.has-background-white-bis{background-color:#fafafa!important}.has-text-weight-light{font-weight:300!important}.has-text-weight-normal{font-weight:400!important}.has-text-weight-medium{font-weight:500!important}.has-text-weight-semibold{font-weight:600!important}.has-text-weight-bold{font-weight:700!important}.is-family-primary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family:monospace!important}.is-block{display:block!important}@media screen and (max-width:768px){.is-block-mobile{display:block!important}}@media screen and (min-width:769px),print{.is-block-tablet{display:block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1023px){.is-block-touch{display:block!important}}@media screen and (min-width:1024px){.is-block-desktop{display:block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-block-desktop-only{display:block!important}}@media screen and (min-width:1216px){.is-block-widescreen{display:block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-block-widescreen-only{display:block!important}}@media screen and (min-width:1408px){.is-block-fullhd{display:block!important}}.is-flex{display:flex!important}@media screen and (max-width:768px){.is-flex-mobile{display:flex!important}}@media screen and (min-width:769px),print{.is-flex-tablet{display:flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1023px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1024px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-flex-desktop-only{display:flex!important}}@media screen and (min-width:1216px){.is-flex-widescreen{display:flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-flex-widescreen-only{display:flex!important}}@media screen and (min-width:1408px){.is-flex-fullhd{display:flex!important}}.is-inline{display:inline!important}@media screen and (max-width:768px){.is-inline-mobile{display:inline!important}}@media screen and (min-width:769px),print{.is-inline-tablet{display:inline!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1023px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1024px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-desktop-only{display:inline!important}}@media screen and (min-width:1216px){.is-inline-widescreen{display:inline!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-widescreen-only{display:inline!important}}@media screen and (min-width:1408px){.is-inline-fullhd{display:inline!important}}.is-inline-block{display:inline-block!important}@media screen and (max-width:768px){.is-inline-block-mobile{display:inline-block!important}}@media screen and (min-width:769px),print{.is-inline-block-tablet{display:inline-block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1023px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1024px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-block-desktop-only{display:inline-block!important}}@media screen and (min-width:1216px){.is-inline-block-widescreen{display:inline-block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-block-widescreen-only{display:inline-block!important}}@media screen and (min-width:1408px){.is-inline-block-fullhd{display:inline-block!important}}.is-inline-flex{display:inline-flex!important}@media screen and (max-width:768px){.is-inline-flex-mobile{display:inline-flex!important}}@media screen and (min-width:769px),print{.is-inline-flex-tablet{display:inline-flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1023px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1024px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-flex-desktop-only{display:inline-flex!important}}@media screen and (min-width:1216px){.is-inline-flex-widescreen{display:inline-flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-flex-widescreen-only{display:inline-flex!important}}@media screen and (min-width:1408px){.is-inline-flex-fullhd{display:inline-flex!important}}.is-hidden{display:none!important}.is-sr-only{border:none!important;clip:rect(0,0,0,0)!important;height:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.01em!important}@media screen and (max-width:768px){.is-hidden-mobile{display:none!important}}@media screen and (min-width:769px),print{.is-hidden-tablet{display:none!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1023px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1024px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-hidden-desktop-only{display:none!important}}@media screen and (min-width:1216px){.is-hidden-widescreen{display:none!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-hidden-widescreen-only{display:none!important}}@media screen and (min-width:1408px){.is-hidden-fullhd{display:none!important}}.is-invisible{visibility:hidden!important}@media screen and (max-width:768px){.is-invisible-mobile{visibility:hidden!important}}@media screen and (min-width:769px),print{.is-invisible-tablet{visibility:hidden!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1023px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1024px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-invisible-desktop-only{visibility:hidden!important}}@media screen and (min-width:1216px){.is-invisible-widescreen{visibility:hidden!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-invisible-widescreen-only{visibility:hidden!important}}@media screen and (min-width:1408px){.is-invisible-fullhd{visibility:hidden!important}}.is-marginless{margin:0!important}.is-paddingless{padding:0!important}.is-radiusless{border-radius:0!important}.is-shadowless{box-shadow:none!important}.is-relative{position:relative!important}.box{background-color:#fff;border-radius:6px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px #3273dc}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #3273dc}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.375em - 1px);padding-left:.75em;padding-right:.75em;padding-top:calc(.375em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.375em - 1px);margin-right:.1875em}.button .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:calc(-.375em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.375em - 1px);margin-right:calc(-.375em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#3273dc;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-hovered,.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined.is-focused,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined.is-loading.is-focused::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined.is-focused,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-hovered,.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined.is-focused,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined.is-loading.is-focused::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined.is-focused,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:#363636}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:#363636}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:#363636}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:#363636}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.button.is-light.is-inverted{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted.is-hovered,.button.is-light.is-inverted:hover{background-color:#292929}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:#363636;border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined.is-focused,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined.is-loading.is-focused::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-light.is-inverted.is-outlined.is-focused,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:#363636;color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark{background-color:#363636;border-color:transparent;color:#f5f5f5}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#f5f5f5}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#f5f5f5}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:transparent;box-shadow:none}.button.is-dark.is-inverted{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted.is-hovered,.button.is-dark.is-inverted:hover{background-color:#e8e8e8}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#f5f5f5;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined.is-focused,.button.is-dark.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined.is-loading.is-focused::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading:hover::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-dark.is-inverted.is-outlined.is-focused,.button.is-dark.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#f5f5f5;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:transparent;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-hovered,.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined.is-focused,.button.is-primary.is-outlined.is-hovered,.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined.is-loading.is-focused::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-outlined.is-loading:focus::after,.button.is-primary.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined.is-focused,.button.is-primary.is-inverted.is-outlined.is-hovered,.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link{background-color:#3273dc;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#276cda;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#2366d1;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#3273dc;border-color:transparent;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-hovered,.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3273dc}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;color:#3273dc}.button.is-link.is-outlined.is-focused,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#3273dc;border-color:#3273dc;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-outlined.is-loading.is-focused::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;box-shadow:none;color:#3273dc}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined.is-focused,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#1496ed;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#118fe4;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:transparent;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-hovered,.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined.is-focused,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee!important}.button.is-info.is-outlined.is-loading.is-focused::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined.is-focused,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #209cee #209cee!important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success{background-color:#23d160;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#22c65b;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#20bc56;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#23d160;border-color:transparent;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#23d160}.button.is-success.is-inverted.is-hovered,.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#23d160}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#23d160;color:#23d160}.button.is-success.is-outlined.is-focused,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#23d160;border-color:#23d160;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #23d160 #23d160!important}.button.is-success.is-outlined.is-loading.is-focused::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#23d160;box-shadow:none;color:#23d160}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined.is-focused,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#23d160}.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #23d160 #23d160!important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-hovered,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined.is-focused,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-outlined.is-loading.is-focused::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined.is-focused,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-danger{background-color:#ff3860;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#ff2b56;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ff1f4b;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#ff3860;border-color:transparent;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted.is-hovered,.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ff3860}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;color:#ff3860}.button.is-danger.is-outlined.is-focused,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#ff3860;border-color:#ff3860;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #ff3860 #ff3860!important}.button.is-danger.is-outlined.is-loading.is-focused::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#ff3860;box-shadow:none;color:#ff3860}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined.is-focused,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#ff3860}.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #ff3860 #ff3860!important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-small{border-radius:2px;font-size:.75rem}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em / 2));top:calc(50% - (1em / 2));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:290486px;padding-left:1em;padding-right:1em}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}@media screen and (min-width:1024px){.container{max-width:960px}.container.is-fluid{margin-left:32px;margin-right:32px;max-width:none}}@media screen and (max-width:1215px){.container.is-widescreen{max-width:1152px}}@media screen and (max-width:1407px){.container.is-fullhd{max-width:1344px}}@media screen and (min-width:1216px){.container{max-width:1152px}}@media screen and (min-width:1408px){.container{max-width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636}.content table th:not([align]){text-align:left}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small{font-size:.75rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:290486px}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;padding:1.25rem 2.5rem 1.25rem 1.5rem;position:relative}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:0 0}.notification>.delete{position:absolute;right:.5rem;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:#363636}.notification.is-dark{background-color:#363636;color:#f5f5f5}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-link{background-color:#3273dc;color:#fff}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-success{background-color:#23d160;color:#fff}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.notification.is-danger{background-color:#ff3860;color:#fff}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#dbdbdb}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right,#fff 30%,#dbdbdb 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right,#0a0a0a 30%,#dbdbdb 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right,#f5f5f5 30%,#dbdbdb 30%)}.progress.is-dark::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#dbdbdb 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#dbdbdb 30%)}.progress.is-link::-webkit-progress-value{background-color:#3273dc}.progress.is-link::-moz-progress-bar{background-color:#3273dc}.progress.is-link::-ms-fill{background-color:#3273dc}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#3273dc 30%,#dbdbdb 30%)}.progress.is-info::-webkit-progress-value{background-color:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#209cee 30%,#dbdbdb 30%)}.progress.is-success::-webkit-progress-value{background-color:#23d160}.progress.is-success::-moz-progress-bar{background-color:#23d160}.progress.is-success::-ms-fill{background-color:#23d160}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#23d160 30%,#dbdbdb 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right,#ffdd57 30%,#dbdbdb 30%)}.progress.is-danger::-webkit-progress-value{background-color:#ff3860}.progress.is-danger::-moz-progress-bar{background-color:#ff3860}.progress.is-danger::-ms-fill{background-color:#ff3860}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#ff3860 30%,#dbdbdb 30%)}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#dbdbdb;background-image:linear-gradient(to right,#4a4a4a 30%,#dbdbdb 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress.is-small{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#f5f5f5}.table td.is-primary,.table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#3273dc;border-color:#3273dc;color:#fff}.table td.is-info,.table th.is-info{background-color:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#23d160;border-color:#23d160;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#ff3860;border-color:#ff3860;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#00d1b2;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table th{color:#363636}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#00d1b2;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:.25em .5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.tags.has-addons .tag:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:#363636}.tag:not(body).is-dark{background-color:#363636;color:#f5f5f5}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-link{background-color:#3273dc;color:#fff}.tag:not(body).is-info{background-color:#209cee;color:#fff}.tag:not(body).is-success{background-color:#23d160;color:#fff}.tag:not(body).is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.tag:not(body).is-danger{background-color:#ff3860;color:#fff}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg);-webkit-transform-origin:center center;transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:290486px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title+.highlight{margin-top:-.75rem}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{align-items:center;background-color:#f5f5f5;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.input,.select select,.textarea{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.input::-moz-placeholder,.select select::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.select select:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input:hover,.is-hovered.input,.is-hovered.textarea,.select select.is-hovered,.select select:hover,.textarea:hover{border-color:#b5b5b5}.input:active,.input:focus,.is-active.input,.is-active.textarea,.is-focused.input,.is-focused.textarea,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{border-color:#3273dc;box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.input[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .select select,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input,.textarea{box-shadow:inset 0 1px 2px rgba(10,10,10,.1);max-width:100%;width:100%}.input[readonly],.textarea[readonly]{box-shadow:none}.is-white.input,.is-white.textarea{border-color:#fff}.is-white.input:active,.is-white.input:focus,.is-white.is-active.input,.is-white.is-active.textarea,.is-white.is-focused.input,.is-white.is-focused.textarea,.is-white.textarea:active,.is-white.textarea:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.is-black.input,.is-black.textarea{border-color:#0a0a0a}.is-black.input:active,.is-black.input:focus,.is-black.is-active.input,.is-black.is-active.textarea,.is-black.is-focused.input,.is-black.is-focused.textarea,.is-black.textarea:active,.is-black.textarea:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.is-light.input,.is-light.textarea{border-color:#f5f5f5}.is-light.input:active,.is-light.input:focus,.is-light.is-active.input,.is-light.is-active.textarea,.is-light.is-focused.input,.is-light.is-focused.textarea,.is-light.textarea:active,.is-light.textarea:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.is-dark.input,.is-dark.textarea{border-color:#363636}.is-dark.input:active,.is-dark.input:focus,.is-dark.is-active.input,.is-dark.is-active.textarea,.is-dark.is-focused.input,.is-dark.is-focused.textarea,.is-dark.textarea:active,.is-dark.textarea:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.is-primary.input,.is-primary.textarea{border-color:#00d1b2}.is-primary.input:active,.is-primary.input:focus,.is-primary.is-active.input,.is-primary.is-active.textarea,.is-primary.is-focused.input,.is-primary.is-focused.textarea,.is-primary.textarea:active,.is-primary.textarea:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.is-link.input,.is-link.textarea{border-color:#3273dc}.is-link.input:active,.is-link.input:focus,.is-link.is-active.input,.is-link.is-active.textarea,.is-link.is-focused.input,.is-link.is-focused.textarea,.is-link.textarea:active,.is-link.textarea:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.is-info.input,.is-info.textarea{border-color:#209cee}.is-info.input:active,.is-info.input:focus,.is-info.is-active.input,.is-info.is-active.textarea,.is-info.is-focused.input,.is-info.is-focused.textarea,.is-info.textarea:active,.is-info.textarea:focus{box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.is-success.input,.is-success.textarea{border-color:#23d160}.is-success.input:active,.is-success.input:focus,.is-success.is-active.input,.is-success.is-active.textarea,.is-success.is-focused.input,.is-success.is-focused.textarea,.is-success.textarea:active,.is-success.textarea:focus{box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.is-warning.input,.is-warning.textarea{border-color:#ffdd57}.is-warning.input:active,.is-warning.input:focus,.is-warning.is-active.input,.is-warning.is-active.textarea,.is-warning.is-focused.input,.is-warning.is-focused.textarea,.is-warning.textarea:active,.is-warning.textarea:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.is-danger.input,.is-danger.textarea{border-color:#ff3860}.is-danger.input:active,.is-danger.input:focus,.is-danger.is-active.input,.is-danger.is-active.textarea,.is-danger.is-focused.input,.is-danger.is-focused.textarea,.is-danger.textarea:active,.is-danger.textarea:focus{box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.is-small.input,.is-small.textarea{border-radius:2px;font-size:.75rem}.is-medium.input,.is-medium.textarea{font-size:1.25rem}.is-large.input,.is-large.textarea{font-size:1.5rem}.is-fullwidth.input,.is-fullwidth.textarea{display:block;width:100%}.is-inline.input,.is-inline.textarea{display:inline;width:auto}.input.is-rounded{border-radius:290486px;padding-left:1em;padding-right:1em}.input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:.625em;resize:vertical}.textarea:not([rows]){max-height:600px;min-height:120px}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.25em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#3273dc;right:1.125em;z-index:4}.select.is-rounded select{border-radius:290486px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#3273dc}.select.is-link select{border-color:#3273dc}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#2366d1}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.select.is-info:not(:hover)::after{border-color:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#118fe4}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(32,156,238,.25)}.select.is-success:not(:hover)::after{border-color:#23d160}.select.is-success select{border-color:#23d160}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#20bc56}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(35,209,96,.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd83d}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.select.is-danger:not(:hover)::after{border-color:#ff3860}.select.is-danger select{border-color:#ff3860}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ff1f4b}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(255,56,96,.25)}.select.is-small{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#7a7a7a}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;-webkit-transform:none;transform:none}.select.is-loading.is-small:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:#363636}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:#363636}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:#363636}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:#363636}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#f5f5f5}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#f5f5f5}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#f5f5f5}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#f5f5f5}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#3273dc;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#276cda;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,115,220,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#2366d1;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#209cee;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#1496ed;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(32,156,238,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#118fe4;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#23d160;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#22c65b;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(35,209,96,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#20bc56;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,221,87,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#ff3860;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#ff2b56;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,56,96,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ff1f4b;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:left;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#3273dc}.help.is-info{color:#209cee}.help.is-success{color:#23d160}.help.is-warning{color:#ffdd57}.help.is-danger{color:#ff3860}.field:not(:last-child){margin-bottom:.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus:hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width:769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width:768px){.field-label{margin-bottom:.5rem}}@media screen and (min-width:769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width:769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:left}.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#7a7a7a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.25em;pointer-events:none;position:absolute;top:0;width:2.25em;z-index:4}.control.has-icons-left .input,.control.has-icons-left .select select{padding-left:2.25em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right .select select{padding-right:2.25em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute!important;right:.625em;top:.625em;z-index:4}.control.is-loading.is-small:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#3273dc;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);color:#4a4a4a;max-width:100%;position:relative}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 1px 2px rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem}.card-image{display:block;position:relative}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;border-top:1px solid #dbdbdb;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #dbdbdb}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:left;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#3273dc;color:#fff}.dropdown-divider{background-color:#dbdbdb;border:none;display:block;height:1px;margin:.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width:769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .subtitle,.level-item .title{margin-bottom:0}@media screen and (max-width:768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width:769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width:768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width:769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width:769px),print{.level-right{display:flex}}.list{background-color:#fff;border-radius:4px;box-shadow:0 2px 3px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1)}.list-item{display:block;padding:.5em 1em}.list-item:not(a){color:#4a4a4a}.list-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-item:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px}.list-item:not(:last-child){border-bottom:1px solid #dbdbdb}.list-item.is-active{background-color:#3273dc;color:#fff}a.list-item{background-color:#f5f5f5;cursor:pointer}.media{align-items:flex-start;display:flex;text-align:left}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:left}@media screen and (max-width:768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#3273dc;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff;color:#4d4d4d}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a;color:#090909}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:#363636}.message.is-light .message-body{border-color:#f5f5f5;color:#505050}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#f5f5f5}.message.is-dark .message-body{border-color:#363636;color:#2a2a2a}.message.is-primary{background-color:#f5fffd}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#021310}.message.is-link{background-color:#f6f9fe}.message.is-link .message-header{background-color:#3273dc;color:#fff}.message.is-link .message-body{border-color:#3273dc;color:#22509a}.message.is-info{background-color:#f6fbfe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#12537e}.message.is-success{background-color:#f6fef9}.message.is-success .message-header{background-color:#23d160;color:#fff}.message.is-success .message-body{border-color:#23d160;color:#0e301a}.message.is-warning{background-color:#fffdf5}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#3b3108}.message.is-danger{background-color:#fff5f7}.message.is-danger .message-header{background-color:#ff3860;color:#fff}.message.is-danger .message-body{border-color:#ff3860;color:#cd0930}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px),print{.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-foot,.modal-card-head{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#363636;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width:1024px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand .navbar-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:#363636}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:#363636}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-brand .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-burger{color:#363636}@media screen and (min-width:1024px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:#363636}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:#363636}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:#363636}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#363636}}.navbar.is-dark{background-color:#363636;color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-burger{color:#f5f5f5}@media screen and (min-width:1024px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#f5f5f5}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#f5f5f5}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#f5f5f5}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#f5f5f5}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#3273dc;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#3273dc;color:#fff}}.navbar.is-info{background-color:#209cee;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#118fe4;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#23d160;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#20bc56;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#23d160;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#ff3860;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ff1f4b;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#ff3860;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;-webkit-transform-origin:center;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,-webkit-transform;transition-property:background-color,opacity,transform;transition-property:background-color,opacity,transform,-webkit-transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:nth-child(1){-webkit-transform:translateY(5px) rotate(45deg);transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){-webkit-transform:translateY(-5px) rotate(-45deg);transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#3273dc}.navbar-item{display:block;flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#3273dc}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#3273dc;border-bottom-style:solid;border-bottom-width:3px;color:#3273dc;padding-bottom:calc(.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#3273dc;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:.5rem 0}@media screen and (max-width:1023px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover{background-color:transparent!important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent!important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item{display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{-webkit-transform:rotate(135deg) translate(.25em,-.25em);transform:rotate(135deg) translate(.25em,-.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{opacity:1;pointer-events:auto;-webkit-transform:translateY(0);transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));-webkit-transform:translateY(-5px);transform:translateY(-5px);transition-duration:86ms;transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:focus):not(:hover),a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:290486px}.pagination.is-rounded .pagination-link{border-radius:290486px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.25em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#3273dc}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#3273dc;border-color:#3273dc;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width:769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel-block,.panel-heading,.panel-tabs{border-bottom:1px solid #dbdbdb;border-left:1px solid #dbdbdb;border-right:1px solid #dbdbdb}.panel-block:first-child,.panel-heading:first-child,.panel-tabs:first-child{border-top:1px solid #dbdbdb}.panel-heading{background-color:#f5f5f5;border-radius:4px 4px 0 0;color:#363636;font-size:1.25em;font-weight:300;line-height:1.25;padding:.5em .75em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#3273dc}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .75em}.panel-block input[type=checkbox]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#3273dc;color:#363636}.panel-block.is-active .panel-icon{color:#3273dc}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#7a7a7a;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#3273dc;color:#3273dc}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:transparent!important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-radius:4px 0 0 4px}.tabs.is-toggle li:last-child a{border-radius:0 4px 4px 0}.tabs.is-toggle li.is-active a{background-color:#3273dc;border-color:#3273dc;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:290486px;border-top-left-radius:290486px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}.tabs.is-small{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0}.columns.is-mobile>.column.is-1{flex:none;width:8.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width:768px){.column.is-narrow-mobile{flex:none}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0}.column.is-1-mobile{flex:none;width:8.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width:769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width:1023px){.column.is-narrow-touch{flex:none}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0}.column.is-1-touch{flex:none;width:8.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1024px){.column.is-narrow-desktop{flex:none}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0}.column.is-1-desktop{flex:none;width:8.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width:1216px){.column.is-narrow-widescreen{flex:none}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0}.column.is-1-widescreen{flex:none;width:8.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width:1408px){.column.is-narrow-fullhd{flex:none}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0}.column.is-1-fullhd{flex:none;width:8.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0!important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap:0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable .column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap:0rem}@media screen and (max-width:768px){.columns.is-variable.is-0-mobile{--columnGap:0rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-0-tablet{--columnGap:0rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1023px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1024px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-0-desktop-only{--columnGap:0rem}}@media screen and (min-width:1216px){.columns.is-variable.is-0-widescreen{--columnGap:0rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-0-widescreen-only{--columnGap:0rem}}@media screen and (min-width:1408px){.columns.is-variable.is-0-fullhd{--columnGap:0rem}}.columns.is-variable.is-1{--columnGap:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-3-fullhd{--columnGap:0.75rem}}.columns.is-variable.is-4{--columnGap:1rem}@media screen and (max-width:768px){.columns.is-variable.is-4-mobile{--columnGap:1rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-4-tablet{--columnGap:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1023px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1024px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-4-desktop-only{--columnGap:1rem}}@media screen and (min-width:1216px){.columns.is-variable.is-4-widescreen{--columnGap:1rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-4-widescreen-only{--columnGap:1rem}}@media screen and (min-width:1408px){.columns.is-variable.is-4-fullhd{--columnGap:1rem}}.columns.is-variable.is-5{--columnGap:1.25rem}@media screen and (max-width:768px){.columns.is-variable.is-5-mobile{--columnGap:1.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-5-tablet{--columnGap:1.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-5-desktop-only{--columnGap:1.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-5-widescreen{--columnGap:1.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-5-widescreen-only{--columnGap:1.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-5-fullhd{--columnGap:1.25rem}}.columns.is-variable.is-6{--columnGap:1.5rem}@media screen and (max-width:768px){.columns.is-variable.is-6-mobile{--columnGap:1.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-6-tablet{--columnGap:1.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-6-desktop-only{--columnGap:1.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-6-widescreen{--columnGap:1.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-6-widescreen-only{--columnGap:1.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-6-fullhd{--columnGap:1.5rem}}.columns.is-variable.is-7{--columnGap:1.75rem}@media screen and (max-width:768px){.columns.is-variable.is-7-mobile{--columnGap:1.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-7-tablet{--columnGap:1.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-7-desktop-only{--columnGap:1.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-7-widescreen{--columnGap:1.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-7-widescreen-only{--columnGap:1.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-7-fullhd{--columnGap:1.75rem}}.columns.is-variable.is-8{--columnGap:2rem}@media screen and (max-width:768px){.columns.is-variable.is-8-mobile{--columnGap:2rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-8-tablet{--columnGap:2rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1023px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1024px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-8-desktop-only{--columnGap:2rem}}@media screen and (min-width:1216px){.columns.is-variable.is-8-widescreen{--columnGap:2rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-8-widescreen-only{--columnGap:2rem}}@media screen and (min-width:1408px){.columns.is-variable.is-8-fullhd{--columnGap:2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0!important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem!important}@media screen and (min-width:769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1023px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}@media screen and (max-width:768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:#363636}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:#363636}.hero.is-light .subtitle{color:rgba(54,54,54,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:#363636}@media screen and (max-width:1023px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(54,54,54,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:#363636}.hero.is-light .tabs a{color:#363636;opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:#363636}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:#363636;border-color:#363636;color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}}.hero.is-dark{background-color:#363636;color:#f5f5f5}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#f5f5f5}.hero.is-dark .subtitle{color:rgba(245,245,245,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#f5f5f5}@media screen and (max-width:1023px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(245,245,245,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#f5f5f5}.hero.is-dark .tabs a{color:#f5f5f5;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#f5f5f5}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:#363636}.hero.is-dark.is-bold{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}@media screen and (max-width:768px){.hero.is-dark.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#3273dc;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-link .navbar-menu{background-color:#3273dc}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#2366d1;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3273dc}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}}.hero.is-info{background-color:#209cee;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-info .navbar-menu{background-color:#209cee}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#118fe4;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#04a6d7 0,#209cee 71%,#3287f5 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#04a6d7 0,#209cee 71%,#3287f5 100%)}}.hero.is-success{background-color:#23d160;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-success .navbar-menu{background-color:#23d160}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#20bc56;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#23d160}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#12af2f 0,#23d160 71%,#2ce28a 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#12af2f 0,#23d160 71%,#2ce28a 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}}.hero.is-danger{background-color:#ff3860;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-danger .navbar-menu{background-color:#ff3860}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ff1f4b;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ff3860}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#ff0561 0,#ff3860 71%,#ff5257 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ff0561 0,#ff3860 71%,#ff5257 100%)}}.hero.is-small .hero-body{padding-bottom:1.5rem;padding-top:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding-bottom:9rem;padding-top:9rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding-bottom:18rem;padding-top:18rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.hero-video.is-transparent{opacity:.3}@media screen and (max-width:768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width:768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:.75rem}}@media screen and (min-width:769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section.is-medium{padding:9rem 1.5rem}.section.is-large{padding:18rem 1.5rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome-5.7.2.min.css b/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome-5.7.2.min.css new file mode 100644 index 00000000000..a74835e25b6 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome-5.7.2.min.css @@ -0,0 +1 @@ +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;font-display:auto;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome.min.css b/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome.min.css new file mode 100644 index 00000000000..812418ae905 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/fontawesome.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.2.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:a 2s infinite linear}.fa-pulse{animation:a 1s infinite steps(8)}@keyframes a{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blind:before{content:"\f29d"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-certificate:before{content:"\f0a3"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-concierge-bell:before{content:"\f562"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-credit-card:before{content:"\f09d"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-deviantart:before{content:"\f1bd"}.fa-diagnoses:before{content:"\f470"}.fa-dice:before{content:"\f522"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-gift:before{content:"\f06b"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hashtag:before{content:"\f292"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-internet-explorer:before{content:"\f26b"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mercury:before{content:"\f223"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-motorcycle:before{content:"\f21c"}.fa-mouse-pointer:before{content:"\f245"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-people-carry:before{content:"\f4ce"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poo:before{content:"\f2fe"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-r-project:before{content:"\f4f7"}.fa-random:before{content:"\f074"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-rendact:before{content:"\f3e4"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-search:before{content:"\f002"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skull:before{content:"\f54c"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowflake:before{content:"\f2dc"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toolbox:before{content:"\f552"}.fa-tooth:before{content:"\f5c9"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/main.css b/tests/wpt/web-platform-tests/tools/wave/www/css/main.css new file mode 100644 index 00000000000..7edbb0f3bae --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/main.css @@ -0,0 +1,101 @@ +h2 { + font-weight: bold; + margin-bottom: 10px; +} + +.site-logo { + max-width: 300px; + margin-bottom: 30px; + margin-left: -15px; +} + +.page-description { + max-width: 700px; + margin-top: 50px; +} + +.field-controls { + padding-top: 25px; +} + +#api-controls { + margin-top: 15px; + max-width: 850px; +} + +#select-none { + margin-right: 25px; +} + +.test-count-container { + vertical-align: sub; + margin-left: 10px; +} + +.section-heading { + font-size: 18px; + margin-top: 25px; + margin-bottom: 0; + font-weight: bold; +} + +.button-group { + margin-top: 30px; +} + +.mb-1 { + margin-bottom: 10px; +} + +.form-group { + display: inline-block; +} + +.form-group--offset { + margin-left: 25px; +} + +.filter-group { + margin-top: 30px; + padding-top: 15px; + padding-bottom: 20px; + border-top: 1px solid #d2d2d2; + border-bottom: 1px solid #d2d2d2; +} + +.focused { + /* box-shadow: inset -3px -3px 0 red, inset 3px 3px 0 red; */ +} + +.focused:after { + display: block; + position: absolute; + border: solid 3px red; + content: ""; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.button.is-light.is-focused:not(:active), +.button.is-light:focus:not(:active) { + box-shadow: 0 0 0 0.125em rgba(0, 0, 0, 0.2); +} + +.button.is-info.is-focused:not(:active), +.button.is-info:focus:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +@media screen and (min-width: 560px) { + #api-controls { + columns: 2; + } +} + +@media screen and (min-width: 780px) { + #api-controls { + columns: 3; + } +} diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/result.css b/tests/wpt/web-platform-tests/tools/wave/www/css/result.css new file mode 100644 index 00000000000..6f944a0a83f --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/result.css @@ -0,0 +1,75 @@ +body { + margin: 0; + padding: 0; + display: flex; + justify-content: center; + font-family: "Noto Sans", sans-serif; + background-color: white; + color: #000; +} + +.header { + display: flex; + margin: 50px 0 30px 0; +} + +.header :first-child { + flex: 1; +} + +.site-logo { + max-width: 300px; + margin-left: -15px; +} + +.content { + width: 1000px; +} + +#test-path, +#token { + font-family: monospace; + font-size: 12pt; +} + +.pass { + color: green; +} + +.fail { + color: red; +} + +.timeout { + color: rgb(224, 127, 0); +} + +.not-run { + color: blue; +} + +.api-result-timeoutfiles { + display: none; /* don't display for now */ + flex-basis: 100%; +} + +#header { + display: flex; + align-items: center; +} + +#header > :first-child { + flex: 1; +} + +#controls-wrapper { + display: flex; +} + +.no-border-radius { + border-radius: 0; +} + +#results-table .button { + margin: 0 2px; +} diff --git a/tests/wpt/web-platform-tests/tools/wave/www/css/style.css b/tests/wpt/web-platform-tests/tools/wave/www/css/style.css new file mode 100644 index 00000000000..9264a47bc5d --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/css/style.css @@ -0,0 +1,86 @@ +body { + width: 100vw; + height: 100vh; + padding: 0; + margin: 0; + color: #000; +} + +.section { + max-width: 1000px; + margin: 0 auto; + padding-left: 0; + padding-right: 0; +} + +.site-logo { + max-width: 300px; + margin-bottom: 30px; + margin-left: -15px; +} + +.site-header { + margin-bottom: 50px; +} + +#content { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} + +#qr-code { + padding: 10px; + border: 1px solid rgb(200, 200, 200); + border-radius: 3px; +} + +#button-wrapper { + display: flex; + margin: 20px 0; +} + +#button-wrapper :not(:first-child) { + margin-left: 15px; +} + +#token, +#test-path { + font-family: monospace; + font-size: 12pt; +} + +#details-wrapper { + display: flex; + flex-direction: column; + max-width: 600px; + margin-top: 20px; +} + +.prompt { + display: flex; + flex-direction: column; + justify-content: center; + width: 700px; +} + +.detail { + margin: 2px 0; + display: flex; + width: 100%; +} + +.detail :first-child { + width: 150px; + flex: none; + font-weight: bold; +} + +.detail div { + flex: 1; +} + +.mb-2 { + margin-bottom: 20px; +} diff --git a/tests/wpt/web-platform-tests/tools/wave/www/favicon.ico b/tests/wpt/web-platform-tests/tools/wave/www/favicon.ico new file mode 100644 index 00000000000..46d0d17d7b9 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/favicon.ico differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/finish.html b/tests/wpt/web-platform-tests/tools/wave/www/finish.html new file mode 100644 index 00000000000..403cb2879e6 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/finish.html @@ -0,0 +1,215 @@ + + + + + Session Finished - Web Platform Test Runner + + + + + + + + +
+ + +
+
+
+
+
+ Create New Session +
+ +
+
+

Details

+
+
Token:
+
+
+
+
User Agent:
+
+
+
+
Test Types:
+
+
+
+
Total Test Files:
+
+
+
+
Reference Tokens:
+
+
+
+
Test Timeouts:
+
+
+
+
Test Paths:
+
+
+
+
+
+
+ + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/index.html b/tests/wpt/web-platform-tests/tools/wave/www/index.html new file mode 100644 index 00000000000..fbfec41d619 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/index.html @@ -0,0 +1,259 @@ + + + + + + Web Media API Snapshot Test Suite + + + + + + + + +
+
+ WAVE (Web Application Video Ecosystem) Project Logo + +

+ WAVE WMAS Test Suite +

+

+ GitHub - +

+
+ +
+

+ New test session +

+
+
+
+
+
+ + + + + + + + + + + + + +
+ Token: +
+ Expires: +
+

(Session start revokes expiration.)

+
+ +

+ Configure a new session on a second device by scanning the + QR-Code, or click the button: +

+
+ + Configure Session +
+

+ The tests will start running in this window, as soon as the + session is started from the configuration view. +

+
+
+
+ +
+

+ Resume running session +

+ +
+
+
+ +
+
+
+
+ + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/LICENSE b/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/LICENSE new file mode 100644 index 00000000000..93c33233fa5 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/LICENSE @@ -0,0 +1,14 @@ +The MIT License (MIT) +--------------------- +Copyright (c) 2012 davidshimjs + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/qrcode.js b/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/qrcode.js new file mode 100644 index 00000000000..45e5d7b974a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/davidshimjs/qrcode.js @@ -0,0 +1,1533 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode +;(function () { + // --------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + // --------------------------------------------------------------------- + function QR8bitByte (data) { + this.mode = QRMode.MODE_8BIT_BYTE + this.data = data + this.parsedData = [] + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = [] + var code = this.data.charCodeAt(i) + + if (code > 0x10000) { + byteArray[0] = 0xf0 | ((code & 0x1c0000) >>> 18) + byteArray[1] = 0x80 | ((code & 0x3f000) >>> 12) + byteArray[2] = 0x80 | ((code & 0xfc0) >>> 6) + byteArray[3] = 0x80 | (code & 0x3f) + } else if (code > 0x800) { + byteArray[0] = 0xe0 | ((code & 0xf000) >>> 12) + byteArray[1] = 0x80 | ((code & 0xfc0) >>> 6) + byteArray[2] = 0x80 | (code & 0x3f) + } else if (code > 0x80) { + byteArray[0] = 0xc0 | ((code & 0x7c0) >>> 6) + byteArray[1] = 0x80 | (code & 0x3f) + } else { + byteArray[0] = code + } + + this.parsedData.push(byteArray) + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData) + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191) + this.parsedData.unshift(187) + this.parsedData.unshift(239) + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8) + } + } + } + + function QRCodeModel (typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber + this.errorCorrectLevel = errorCorrectLevel + this.modules = null + this.moduleCount = 0 + this.dataCache = null + this.dataList = [] + } + + QRCodeModel.prototype = { + addData: function (data) { + var newData = new QR8bitByte(data) + this.dataList.push(newData) + this.dataCache = null + }, + isDark: function (row, col) { + if ( + row < 0 || + this.moduleCount <= row || + col < 0 || + this.moduleCount <= col + ) { + throw new Error(row + ',' + col) + } + return this.modules[row][col] + }, + getModuleCount: function () { + return this.moduleCount + }, + make: function () { + this.makeImpl(false, this.getBestMaskPattern()) + }, + makeImpl: function (test, maskPattern) { + this.moduleCount = this.typeNumber * 4 + 17 + this.modules = new Array(this.moduleCount) + for (var row = 0; row < this.moduleCount; row++) { + this.modules[row] = new Array(this.moduleCount) + for (var col = 0; col < this.moduleCount; col++) { + this.modules[row][col] = null + } + } + this.setupPositionProbePattern(0, 0) + this.setupPositionProbePattern(this.moduleCount - 7, 0) + this.setupPositionProbePattern(0, this.moduleCount - 7) + this.setupPositionAdjustPattern() + this.setupTimingPattern() + this.setupTypeInfo(test, maskPattern) + if (this.typeNumber >= 7) { + this.setupTypeNumber(test) + } + if (this.dataCache == null) { + this.dataCache = QRCodeModel.createData( + this.typeNumber, + this.errorCorrectLevel, + this.dataList + ) + } + this.mapData(this.dataCache, maskPattern) + }, + setupPositionProbePattern: function (row, col) { + for (var r = -1; r <= 7; r++) { + if (row + r <= -1 || this.moduleCount <= row + r) continue + for (var c = -1; c <= 7; c++) { + if (col + c <= -1 || this.moduleCount <= col + c) continue + if ( + (r >= 0 && r <= 6 && (c == 0 || c == 6)) || + (c >= 0 && c <= 6 && (r == 0 || r == 6)) || + (r >= 2 && r <= 4 && c >= 2 && c <= 4) + ) { + this.modules[row + r][col + c] = true + } else { + this.modules[row + r][col + c] = false + } + } + } + }, + getBestMaskPattern: function () { + var minLostPoint = 0 + var pattern = 0 + for (var i = 0; i < 8; i++) { + this.makeImpl(true, i) + var lostPoint = QRUtil.getLostPoint(this) + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint + pattern = i + } + } + return pattern + }, + createMovieClip: function (target_mc, instance_name, depth) { + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth) + var cs = 1 + this.make() + for (var row = 0; row < this.modules.length; row++) { + var y = row * cs + for (var col = 0; col < this.modules[row].length; col++) { + var x = col * cs + var dark = this.modules[row][col] + if (dark) { + qr_mc.beginFill(0, 100) + qr_mc.moveTo(x, y) + qr_mc.lineTo(x + cs, y) + qr_mc.lineTo(x + cs, y + cs) + qr_mc.lineTo(x, y + cs) + qr_mc.endFill() + } + } + } + return qr_mc + }, + setupTimingPattern: function () { + for (var r = 8; r < this.moduleCount - 8; r++) { + if (this.modules[r][6] != null) { + continue + } + this.modules[r][6] = r % 2 == 0 + } + for (var c = 8; c < this.moduleCount - 8; c++) { + if (this.modules[6][c] != null) { + continue + } + this.modules[6][c] = c % 2 == 0 + } + }, + setupPositionAdjustPattern: function () { + var pos = QRUtil.getPatternPosition(this.typeNumber) + for (var i = 0; i < pos.length; i++) { + for (var j = 0; j < pos.length; j++) { + var row = pos[i] + var col = pos[j] + if (this.modules[row][col] != null) { + continue + } + for (var r = -2; r <= 2; r++) { + for (var c = -2; c <= 2; c++) { + if ( + r == -2 || + r == 2 || + c == -2 || + c == 2 || + (r == 0 && c == 0) + ) { + this.modules[row + r][col + c] = true + } else { + this.modules[row + r][col + c] = false + } + } + } + } + } + }, + setupTypeNumber: function (test) { + var bits = QRUtil.getBCHTypeNumber(this.typeNumber) + for (var i = 0; i < 18; i++) { + var mod = !test && ((bits >> i) & 1) == 1 + this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod + } + for (var i = 0; i < 18; i++) { + var mod = !test && ((bits >> i) & 1) == 1 + this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod + } + }, + setupTypeInfo: function (test, maskPattern) { + var data = (this.errorCorrectLevel << 3) | maskPattern + var bits = QRUtil.getBCHTypeInfo(data) + for (var i = 0; i < 15; i++) { + var mod = !test && ((bits >> i) & 1) == 1 + if (i < 6) { + this.modules[i][8] = mod + } else if (i < 8) { + this.modules[i + 1][8] = mod + } else { + this.modules[this.moduleCount - 15 + i][8] = mod + } + } + for (var i = 0; i < 15; i++) { + var mod = !test && ((bits >> i) & 1) == 1 + if (i < 8) { + this.modules[8][this.moduleCount - i - 1] = mod + } else if (i < 9) { + this.modules[8][15 - i - 1 + 1] = mod + } else { + this.modules[8][15 - i - 1] = mod + } + } + this.modules[this.moduleCount - 8][8] = !test + }, + mapData: function (data, maskPattern) { + var inc = -1 + var row = this.moduleCount - 1 + var bitIndex = 7 + var byteIndex = 0 + for (var col = this.moduleCount - 1; col > 0; col -= 2) { + if (col == 6) col-- + while (true) { + for (var c = 0; c < 2; c++) { + if (this.modules[row][col - c] == null) { + var dark = false + if (byteIndex < data.length) { + dark = ((data[byteIndex] >>> bitIndex) & 1) == 1 + } + var mask = QRUtil.getMask(maskPattern, row, col - c) + if (mask) { + dark = !dark + } + this.modules[row][col - c] = dark + bitIndex-- + if (bitIndex == -1) { + byteIndex++ + bitIndex = 7 + } + } + } + row += inc + if (row < 0 || this.moduleCount <= row) { + row -= inc + inc = -inc + break + } + } + } + } + } + QRCodeModel.PAD0 = 0xec + QRCodeModel.PAD1 = 0x11 + QRCodeModel.createData = function (typeNumber, errorCorrectLevel, dataList) { + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel) + var buffer = new QRBitBuffer() + for (var i = 0; i < dataList.length; i++) { + var data = dataList[i] + buffer.put(data.mode, 4) + buffer.put( + data.getLength(), + QRUtil.getLengthInBits(data.mode, typeNumber) + ) + data.write(buffer) + } + var totalDataCount = 0 + for (var i = 0; i < rsBlocks.length; i++) { + totalDataCount += rsBlocks[i].dataCount + } + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error( + 'code length overflow. (' + + buffer.getLengthInBits() + + '>' + + totalDataCount * 8 + + ')' + ) + } + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4) + } + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false) + } + while (true) { + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break + } + buffer.put(QRCodeModel.PAD0, 8) + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break + } + buffer.put(QRCodeModel.PAD1, 8) + } + return QRCodeModel.createBytes(buffer, rsBlocks) + } + QRCodeModel.createBytes = function (buffer, rsBlocks) { + var offset = 0 + var maxDcCount = 0 + var maxEcCount = 0 + var dcdata = new Array(rsBlocks.length) + var ecdata = new Array(rsBlocks.length) + for (var r = 0; r < rsBlocks.length; r++) { + var dcCount = rsBlocks[r].dataCount + var ecCount = rsBlocks[r].totalCount - dcCount + maxDcCount = Math.max(maxDcCount, dcCount) + maxEcCount = Math.max(maxEcCount, ecCount) + dcdata[r] = new Array(dcCount) + for (var i = 0; i < dcdata[r].length; i++) { + dcdata[r][i] = 0xff & buffer.buffer[i + offset] + } + offset += dcCount + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount) + var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1) + var modPoly = rawPoly.mod(rsPoly) + ecdata[r] = new Array(rsPoly.getLength() - 1) + for (var i = 0; i < ecdata[r].length; i++) { + var modIndex = i + modPoly.getLength() - ecdata[r].length + ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0 + } + } + var totalCodeCount = 0 + for (var i = 0; i < rsBlocks.length; i++) { + totalCodeCount += rsBlocks[i].totalCount + } + var data = new Array(totalCodeCount) + var index = 0 + for (var i = 0; i < maxDcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < dcdata[r].length) { + data[index++] = dcdata[r][i] + } + } + } + for (var i = 0; i < maxEcCount; i++) { + for (var r = 0; r < rsBlocks.length; r++) { + if (i < ecdata[r].length) { + data[index++] = ecdata[r][i] + } + } + } + return data + } + var QRMode = { + MODE_NUMBER: 1 << 0, + MODE_ALPHA_NUM: 1 << 1, + MODE_8BIT_BYTE: 1 << 2, + MODE_KANJI: 1 << 3 + } + var QRErrorCorrectLevel = { L: 1, M: 0, Q: 3, H: 2 } + var QRMaskPattern = { + PATTERN000: 0, + PATTERN001: 1, + PATTERN010: 2, + PATTERN011: 3, + PATTERN100: 4, + PATTERN101: 5, + PATTERN110: 6, + PATTERN111: 7 + } + var QRUtil = { + PATTERN_POSITION_TABLE: [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ], + G15: + (1 << 10) | + (1 << 8) | + (1 << 5) | + (1 << 4) | + (1 << 2) | + (1 << 1) | + (1 << 0), + G18: + (1 << 12) | + (1 << 11) | + (1 << 10) | + (1 << 9) | + (1 << 8) | + (1 << 5) | + (1 << 2) | + (1 << 0), + G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), + getBCHTypeInfo: function (data) { + var d = data << 10 + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { + d ^= + QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)) + } + return ((data << 10) | d) ^ QRUtil.G15_MASK + }, + getBCHTypeNumber: function (data) { + var d = data << 12 + while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { + d ^= + QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)) + } + return (data << 12) | d + }, + getBCHDigit: function (data) { + var digit = 0 + while (data != 0) { + digit++ + data >>>= 1 + } + return digit + }, + getPatternPosition: function (typeNumber) { + return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1] + }, + getMask: function (maskPattern, i, j) { + switch (maskPattern) { + case QRMaskPattern.PATTERN000: + return (i + j) % 2 == 0 + case QRMaskPattern.PATTERN001: + return i % 2 == 0 + case QRMaskPattern.PATTERN010: + return j % 3 == 0 + case QRMaskPattern.PATTERN011: + return (i + j) % 3 == 0 + case QRMaskPattern.PATTERN100: + return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0 + case QRMaskPattern.PATTERN101: + return (i * j) % 2 + (i * j) % 3 == 0 + case QRMaskPattern.PATTERN110: + return ((i * j) % 2 + (i * j) % 3) % 2 == 0 + case QRMaskPattern.PATTERN111: + return ((i * j) % 3 + (i + j) % 2) % 2 == 0 + default: + throw new Error('bad maskPattern:' + maskPattern) + } + }, + getErrorCorrectPolynomial: function (errorCorrectLength) { + var a = new QRPolynomial([1], 0) + for (var i = 0; i < errorCorrectLength; i++) { + a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)) + } + return a + }, + getLengthInBits: function (mode, type) { + if (type >= 1 && type < 10) { + switch (mode) { + case QRMode.MODE_NUMBER: + return 10 + case QRMode.MODE_ALPHA_NUM: + return 9 + case QRMode.MODE_8BIT_BYTE: + return 8 + case QRMode.MODE_KANJI: + return 8 + default: + throw new Error('mode:' + mode) + } + } else if (type < 27) { + switch (mode) { + case QRMode.MODE_NUMBER: + return 12 + case QRMode.MODE_ALPHA_NUM: + return 11 + case QRMode.MODE_8BIT_BYTE: + return 16 + case QRMode.MODE_KANJI: + return 10 + default: + throw new Error('mode:' + mode) + } + } else if (type < 41) { + switch (mode) { + case QRMode.MODE_NUMBER: + return 14 + case QRMode.MODE_ALPHA_NUM: + return 13 + case QRMode.MODE_8BIT_BYTE: + return 16 + case QRMode.MODE_KANJI: + return 12 + default: + throw new Error('mode:' + mode) + } + } else { + throw new Error('type:' + type) + } + }, + getLostPoint: function (qrCode) { + var moduleCount = qrCode.getModuleCount() + var lostPoint = 0 + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount; col++) { + var sameCount = 0 + var dark = qrCode.isDark(row, col) + for (var r = -1; r <= 1; r++) { + if (row + r < 0 || moduleCount <= row + r) { + continue + } + for (var c = -1; c <= 1; c++) { + if (col + c < 0 || moduleCount <= col + c) { + continue + } + if (r == 0 && c == 0) { + continue + } + if (dark == qrCode.isDark(row + r, col + c)) { + sameCount++ + } + } + } + if (sameCount > 5) { + lostPoint += 3 + sameCount - 5 + } + } + } + for (var row = 0; row < moduleCount - 1; row++) { + for (var col = 0; col < moduleCount - 1; col++) { + var count = 0 + if (qrCode.isDark(row, col)) count++ + if (qrCode.isDark(row + 1, col)) count++ + if (qrCode.isDark(row, col + 1)) count++ + if (qrCode.isDark(row + 1, col + 1)) count++ + if (count == 0 || count == 4) { + lostPoint += 3 + } + } + } + for (var row = 0; row < moduleCount; row++) { + for (var col = 0; col < moduleCount - 6; col++) { + if ( + qrCode.isDark(row, col) && + !qrCode.isDark(row, col + 1) && + qrCode.isDark(row, col + 2) && + qrCode.isDark(row, col + 3) && + qrCode.isDark(row, col + 4) && + !qrCode.isDark(row, col + 5) && + qrCode.isDark(row, col + 6) + ) { + lostPoint += 40 + } + } + } + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount - 6; row++) { + if ( + qrCode.isDark(row, col) && + !qrCode.isDark(row + 1, col) && + qrCode.isDark(row + 2, col) && + qrCode.isDark(row + 3, col) && + qrCode.isDark(row + 4, col) && + !qrCode.isDark(row + 5, col) && + qrCode.isDark(row + 6, col) + ) { + lostPoint += 40 + } + } + } + var darkCount = 0 + for (var col = 0; col < moduleCount; col++) { + for (var row = 0; row < moduleCount; row++) { + if (qrCode.isDark(row, col)) { + darkCount++ + } + } + } + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5 + lostPoint += ratio * 10 + return lostPoint + } + } + var QRMath = { + glog: function (n) { + if (n < 1) { + throw new Error('glog(' + n + ')') + } + return QRMath.LOG_TABLE[n] + }, + gexp: function (n) { + while (n < 0) { + n += 255 + } + while (n >= 256) { + n -= 255 + } + return QRMath.EXP_TABLE[n] + }, + EXP_TABLE: new Array(256), + LOG_TABLE: new Array(256) + } + for (var i = 0; i < 8; i++) { + QRMath.EXP_TABLE[i] = 1 << i + } + for (var i = 8; i < 256; i++) { + QRMath.EXP_TABLE[i] = + QRMath.EXP_TABLE[i - 4] ^ + QRMath.EXP_TABLE[i - 5] ^ + QRMath.EXP_TABLE[i - 6] ^ + QRMath.EXP_TABLE[i - 8] + } + for (var i = 0; i < 255; i++) { + QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i + } + function QRPolynomial (num, shift) { + if (num.length == undefined) { + throw new Error(num.length + '/' + shift) + } + var offset = 0 + while (offset < num.length && num[offset] == 0) { + offset++ + } + this.num = new Array(num.length - offset + shift) + for (var i = 0; i < num.length - offset; i++) { + this.num[i] = num[i + offset] + } + } + QRPolynomial.prototype = { + get: function (index) { + return this.num[index] + }, + getLength: function () { + return this.num.length + }, + multiply: function (e) { + var num = new Array(this.getLength() + e.getLength() - 1) + for (var i = 0; i < this.getLength(); i++) { + for (var j = 0; j < e.getLength(); j++) { + num[i + j] ^= QRMath.gexp( + QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)) + ) + } + } + return new QRPolynomial(num, 0) + }, + mod: function (e) { + if (this.getLength() - e.getLength() < 0) { + return this + } + var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)) + var num = new Array(this.getLength()) + for (var i = 0; i < this.getLength(); i++) { + num[i] = this.get(i) + } + for (var i = 0; i < e.getLength(); i++) { + num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio) + } + return new QRPolynomial(num, 0).mod(e) + } + } + function QRRSBlock (totalCount, dataCount) { + this.totalCount = totalCount + this.dataCount = dataCount + } + QRRSBlock.RS_BLOCK_TABLE = [ + [1, 26, 19], + [1, 26, 16], + [1, 26, 13], + [1, 26, 9], + [1, 44, 34], + [1, 44, 28], + [1, 44, 22], + [1, 44, 16], + [1, 70, 55], + [1, 70, 44], + [2, 35, 17], + [2, 35, 13], + [1, 100, 80], + [2, 50, 32], + [2, 50, 24], + [4, 25, 9], + [1, 134, 108], + [2, 67, 43], + [2, 33, 15, 2, 34, 16], + [2, 33, 11, 2, 34, 12], + [2, 86, 68], + [4, 43, 27], + [4, 43, 19], + [4, 43, 15], + [2, 98, 78], + [4, 49, 31], + [2, 32, 14, 4, 33, 15], + [4, 39, 13, 1, 40, 14], + [2, 121, 97], + [2, 60, 38, 2, 61, 39], + [4, 40, 18, 2, 41, 19], + [4, 40, 14, 2, 41, 15], + [2, 146, 116], + [3, 58, 36, 2, 59, 37], + [4, 36, 16, 4, 37, 17], + [4, 36, 12, 4, 37, 13], + [2, 86, 68, 2, 87, 69], + [4, 69, 43, 1, 70, 44], + [6, 43, 19, 2, 44, 20], + [6, 43, 15, 2, 44, 16], + [4, 101, 81], + [1, 80, 50, 4, 81, 51], + [4, 50, 22, 4, 51, 23], + [3, 36, 12, 8, 37, 13], + [2, 116, 92, 2, 117, 93], + [6, 58, 36, 2, 59, 37], + [4, 46, 20, 6, 47, 21], + [7, 42, 14, 4, 43, 15], + [4, 133, 107], + [8, 59, 37, 1, 60, 38], + [8, 44, 20, 4, 45, 21], + [12, 33, 11, 4, 34, 12], + [3, 145, 115, 1, 146, 116], + [4, 64, 40, 5, 65, 41], + [11, 36, 16, 5, 37, 17], + [11, 36, 12, 5, 37, 13], + [5, 109, 87, 1, 110, 88], + [5, 65, 41, 5, 66, 42], + [5, 54, 24, 7, 55, 25], + [11, 36, 12], + [5, 122, 98, 1, 123, 99], + [7, 73, 45, 3, 74, 46], + [15, 43, 19, 2, 44, 20], + [3, 45, 15, 13, 46, 16], + [1, 135, 107, 5, 136, 108], + [10, 74, 46, 1, 75, 47], + [1, 50, 22, 15, 51, 23], + [2, 42, 14, 17, 43, 15], + [5, 150, 120, 1, 151, 121], + [9, 69, 43, 4, 70, 44], + [17, 50, 22, 1, 51, 23], + [2, 42, 14, 19, 43, 15], + [3, 141, 113, 4, 142, 114], + [3, 70, 44, 11, 71, 45], + [17, 47, 21, 4, 48, 22], + [9, 39, 13, 16, 40, 14], + [3, 135, 107, 5, 136, 108], + [3, 67, 41, 13, 68, 42], + [15, 54, 24, 5, 55, 25], + [15, 43, 15, 10, 44, 16], + [4, 144, 116, 4, 145, 117], + [17, 68, 42], + [17, 50, 22, 6, 51, 23], + [19, 46, 16, 6, 47, 17], + [2, 139, 111, 7, 140, 112], + [17, 74, 46], + [7, 54, 24, 16, 55, 25], + [34, 37, 13], + [4, 151, 121, 5, 152, 122], + [4, 75, 47, 14, 76, 48], + [11, 54, 24, 14, 55, 25], + [16, 45, 15, 14, 46, 16], + [6, 147, 117, 4, 148, 118], + [6, 73, 45, 14, 74, 46], + [11, 54, 24, 16, 55, 25], + [30, 46, 16, 2, 47, 17], + [8, 132, 106, 4, 133, 107], + [8, 75, 47, 13, 76, 48], + [7, 54, 24, 22, 55, 25], + [22, 45, 15, 13, 46, 16], + [10, 142, 114, 2, 143, 115], + [19, 74, 46, 4, 75, 47], + [28, 50, 22, 6, 51, 23], + [33, 46, 16, 4, 47, 17], + [8, 152, 122, 4, 153, 123], + [22, 73, 45, 3, 74, 46], + [8, 53, 23, 26, 54, 24], + [12, 45, 15, 28, 46, 16], + [3, 147, 117, 10, 148, 118], + [3, 73, 45, 23, 74, 46], + [4, 54, 24, 31, 55, 25], + [11, 45, 15, 31, 46, 16], + [7, 146, 116, 7, 147, 117], + [21, 73, 45, 7, 74, 46], + [1, 53, 23, 37, 54, 24], + [19, 45, 15, 26, 46, 16], + [5, 145, 115, 10, 146, 116], + [19, 75, 47, 10, 76, 48], + [15, 54, 24, 25, 55, 25], + [23, 45, 15, 25, 46, 16], + [13, 145, 115, 3, 146, 116], + [2, 74, 46, 29, 75, 47], + [42, 54, 24, 1, 55, 25], + [23, 45, 15, 28, 46, 16], + [17, 145, 115], + [10, 74, 46, 23, 75, 47], + [10, 54, 24, 35, 55, 25], + [19, 45, 15, 35, 46, 16], + [17, 145, 115, 1, 146, 116], + [14, 74, 46, 21, 75, 47], + [29, 54, 24, 19, 55, 25], + [11, 45, 15, 46, 46, 16], + [13, 145, 115, 6, 146, 116], + [14, 74, 46, 23, 75, 47], + [44, 54, 24, 7, 55, 25], + [59, 46, 16, 1, 47, 17], + [12, 151, 121, 7, 152, 122], + [12, 75, 47, 26, 76, 48], + [39, 54, 24, 14, 55, 25], + [22, 45, 15, 41, 46, 16], + [6, 151, 121, 14, 152, 122], + [6, 75, 47, 34, 76, 48], + [46, 54, 24, 10, 55, 25], + [2, 45, 15, 64, 46, 16], + [17, 152, 122, 4, 153, 123], + [29, 74, 46, 14, 75, 47], + [49, 54, 24, 10, 55, 25], + [24, 45, 15, 46, 46, 16], + [4, 152, 122, 18, 153, 123], + [13, 74, 46, 32, 75, 47], + [48, 54, 24, 14, 55, 25], + [42, 45, 15, 32, 46, 16], + [20, 147, 117, 4, 148, 118], + [40, 75, 47, 7, 76, 48], + [43, 54, 24, 22, 55, 25], + [10, 45, 15, 67, 46, 16], + [19, 148, 118, 6, 149, 119], + [18, 75, 47, 31, 76, 48], + [34, 54, 24, 34, 55, 25], + [20, 45, 15, 61, 46, 16] + ] + QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) { + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel) + if (rsBlock == undefined) { + throw new Error( + 'bad rs block @ typeNumber:' + + typeNumber + + '/errorCorrectLevel:' + + errorCorrectLevel + ) + } + var length = rsBlock.length / 3 + var list = [] + for (var i = 0; i < length; i++) { + var count = rsBlock[i * 3 + 0] + var totalCount = rsBlock[i * 3 + 1] + var dataCount = rsBlock[i * 3 + 2] + for (var j = 0; j < count; j++) { + list.push(new QRRSBlock(totalCount, dataCount)) + } + } + return list + } + QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) { + switch (errorCorrectLevel) { + case QRErrorCorrectLevel.L: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0] + case QRErrorCorrectLevel.M: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1] + case QRErrorCorrectLevel.Q: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2] + case QRErrorCorrectLevel.H: + return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3] + default: + return undefined + } + } + function QRBitBuffer () { + this.buffer = [] + this.length = 0 + } + QRBitBuffer.prototype = { + get: function (index) { + var bufIndex = Math.floor(index / 8) + return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1 + }, + put: function (num, length) { + for (var i = 0; i < length; i++) { + this.putBit(((num >>> (length - i - 1)) & 1) == 1) + } + }, + getLengthInBits: function () { + return this.length + }, + putBit: function (bit) { + var bufIndex = Math.floor(this.length / 8) + if (this.buffer.length <= bufIndex) { + this.buffer.push(0) + } + if (bit) { + this.buffer[bufIndex] |= 0x80 >>> (this.length % 8) + } + this.length++ + } + } + var QRCodeLimitLength = [ + [17, 14, 11, 7], + [32, 26, 20, 14], + [53, 42, 32, 24], + [78, 62, 46, 34], + [106, 84, 60, 44], + [134, 106, 74, 58], + [154, 122, 86, 64], + [192, 152, 108, 84], + [230, 180, 130, 98], + [271, 213, 151, 119], + [321, 251, 177, 137], + [367, 287, 203, 155], + [425, 331, 241, 177], + [458, 362, 258, 194], + [520, 412, 292, 220], + [586, 450, 322, 250], + [644, 504, 364, 280], + [718, 560, 394, 310], + [792, 624, 442, 338], + [858, 666, 482, 382], + [929, 711, 509, 403], + [1003, 779, 565, 439], + [1091, 857, 611, 461], + [1171, 911, 661, 511], + [1273, 997, 715, 535], + [1367, 1059, 751, 593], + [1465, 1125, 805, 625], + [1528, 1190, 868, 658], + [1628, 1264, 908, 698], + [1732, 1370, 982, 742], + [1840, 1452, 1030, 790], + [1952, 1538, 1112, 842], + [2068, 1628, 1168, 898], + [2188, 1722, 1228, 958], + [2303, 1809, 1283, 983], + [2431, 1911, 1351, 1051], + [2563, 1989, 1423, 1093], + [2699, 2099, 1499, 1139], + [2809, 2213, 1579, 1219], + [2953, 2331, 1663, 1273] + ] + + function _isSupportCanvas () { + return typeof CanvasRenderingContext2D !== 'undefined' + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid () { + var android = false + var sAgent = navigator.userAgent + + if (/android/i.test(sAgent)) { + // android + android = true + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i) + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]) + } + } + + return android + } + + var svgDrawer = (function () { + var Drawing = function (el, htOption) { + this._el = el + this._htOption = htOption + } + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption + var _el = this._el + var nCount = oQRCode.getModuleCount() + var nWidth = Math.floor(_htOption.width / nCount) + var nHeight = Math.floor(_htOption.height / nCount) + + this.clear() + + function makeSVG (tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag) + for (var k in attrs) { + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]) + } + return el + } + + var svg = makeSVG('svg', { + viewBox: '0 0 ' + String(nCount) + ' ' + String(nCount), + width: '100%', + height: '100%', + fill: _htOption.colorLight + }) + svg.setAttributeNS( + 'http://www.w3.org/2000/xmlns/', + 'xmlns:xlink', + 'http://www.w3.org/1999/xlink' + ) + _el.appendChild(svg) + + svg.appendChild( + makeSVG('rect', { + fill: _htOption.colorLight, + width: '100%', + height: '100%' + }) + ) + svg.appendChild( + makeSVG('rect', { + fill: _htOption.colorDark, + width: '1', + height: '1', + id: 'template' + }) + ) + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG('use', { x: String(col), y: String(row) }) + child.setAttributeNS( + 'http://www.w3.org/1999/xlink', + 'href', + '#template' + ) + svg.appendChild(child) + } + } + } + } + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) this._el.removeChild(this._el.lastChild) + } + return Drawing + })() + + var useSVG = document.documentElement.tagName.toLowerCase() === 'svg' + + // Drawing in DOM by using Table tag + var Drawing = useSVG + ? svgDrawer + : !_isSupportCanvas() + ? (function () { + var Drawing = function (el, htOption) { + this._el = el + this._htOption = htOption + } + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption + var _el = this._el + var nCount = oQRCode.getModuleCount() + var nWidth = Math.floor(_htOption.width / nCount) + var nHeight = Math.floor(_htOption.height / nCount) + var aHTML = [''] + + for (var row = 0; row < nCount; row++) { + aHTML.push('') + + for (var col = 0; col < nCount; col++) { + aHTML.push( + '' + ) + } + + aHTML.push('') + } + + aHTML.push('
') + _el.innerHTML = aHTML.join('') + + // Fix the margin values as real size. + var elTable = _el.childNodes[0] + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2 + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2 + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = + nTopMarginTable + 'px ' + nLeftMarginTable + 'px' + } + } + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = '' + } + + return Drawing + })() + : (function () { + // Drawing in Canvas + function _onMakeImage () { + this._elImage.src = this._elCanvas.toDataURL('image/png') + this._elImage.style.display = 'block' + this._elCanvas.style.display = 'none' + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio + var drawImage = CanvasRenderingContext2D.prototype.drawImage + CanvasRenderingContext2D.prototype.drawImage = function ( + image, + sx, + sy, + sw, + sh, + dx, + dy, + dw, + dh + ) { + if ('nodeName' in image && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor + } + } else if (typeof dw === 'undefined') { + arguments[1] *= factor + arguments[2] *= factor + arguments[3] *= factor + arguments[4] *= factor + } + + drawImage.apply(this, arguments) + } + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI (fSuccess, fFail) { + var self = this + self._fFail = fFail + self._fSuccess = fSuccess + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement('img') + var fOnError = function () { + self._bSupportDataURI = false + + if (self._fFail) { + self._fFail.call(self) + } + } + var fOnSuccess = function () { + self._bSupportDataURI = true + + if (self._fSuccess) { + self._fSuccess.call(self) + } + } + + el.onabort = fOnError + el.onerror = fOnError + el.onload = fOnSuccess + el.src = + 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' // the Image contains 1px data. + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self) + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self) + } + } + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false + this._android = _getAndroid() + + this._htOption = htOption + this._elCanvas = document.createElement('canvas') + this._elCanvas.width = htOption.width + this._elCanvas.height = htOption.height + el.appendChild(this._elCanvas) + this._el = el + this._oContext = this._elCanvas.getContext('2d') + this._bIsPainted = false + this._elImage = document.createElement('img') + this._elImage.alt = 'Scan me!' + this._elImage.style.display = 'none' + this._el.appendChild(this._elImage) + this._bSupportDataURI = null + } + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage + var _oContext = this._oContext + var _htOption = this._htOption + + var nCount = oQRCode.getModuleCount() + var nWidth = _htOption.width / nCount + var nHeight = _htOption.height / nCount + var nRoundedWidth = Math.round(nWidth) + var nRoundedHeight = Math.round(nHeight) + + _elImage.style.display = 'none' + this.clear() + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col) + var nLeft = col * nWidth + var nTop = row * nHeight + _oContext.strokeStyle = bIsDark + ? _htOption.colorDark + : _htOption.colorLight + _oContext.lineWidth = 1 + _oContext.fillStyle = bIsDark + ? _htOption.colorDark + : _htOption.colorLight + _oContext.fillRect(nLeft, nTop, nWidth, nHeight) + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ) + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ) + } + } + + this._bIsPainted = true + } + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage) + } + } + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted + } + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect( + 0, + 0, + this._elCanvas.width, + this._elCanvas.height + ) + this._bIsPainted = false + } + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber + } + + return Math.floor(nNumber * 1000) / 1000 + } + + return Drawing + })() + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber (sText, nCorrectLevel) { + var nType = 1 + var length = _getUTF8Length(sText) + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0 + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L: + nLimit = QRCodeLimitLength[i][0] + break + case QRErrorCorrectLevel.M: + nLimit = QRCodeLimitLength[i][1] + break + case QRErrorCorrectLevel.Q: + nLimit = QRCodeLimitLength[i][2] + break + case QRErrorCorrectLevel.H: + nLimit = QRCodeLimitLength[i][3] + break + } + + if (length <= nLimit) { + break + } else { + nType++ + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error('Too long data') + } + + return nType + } + + function _getUTF8Length (sText) { + var replacedText = encodeURI(sText) + .toString() + .replace(/\%[0-9a-fA-F]{2}/g, 'a') + return replacedText.length + (replacedText.length != sText ? 3 : 0) + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width: 256, + height: 256, + typeNumber: 4, + colorDark: '#000000', + colorLight: '#ffffff', + correctLevel: QRErrorCorrectLevel.H + } + + if (typeof vOption === 'string') { + vOption = { + text: vOption + } + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i] + } + } + + if (typeof el === 'string') { + el = document.getElementById(el) + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer + } + + this._android = _getAndroid() + this._el = el + this._oQRCode = null + this._oDrawing = new Drawing(this._el, this._htOption) + + if (this._htOption.text) { + this.makeCode(this._htOption.text) + } + } + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel( + _getTypeNumber(sText, this._htOption.correctLevel), + this._htOption.correctLevel + ) + this._oQRCode.addData(sText) + this._oQRCode.make() + this._el.title = sText + this._oDrawing.draw(this._oQRCode) + this.makeImage() + } + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if ( + typeof this._oDrawing.makeImage === 'function' && + (!this._android || this._android >= 3) + ) { + this._oDrawing.makeImage() + } + } + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear() + } + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel +})() diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/keycodes.js b/tests/wpt/web-platform-tests/tools/wave/www/lib/keycodes.js new file mode 100644 index 00000000000..2d01b035ab8 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/keycodes.js @@ -0,0 +1,88 @@ +if (typeof KeyEvent != "undefined") { + if (typeof KeyEvent.VK_LEFT != "undefined") { + var VK_LEFT = KeyEvent.VK_LEFT; + var VK_UP = KeyEvent.VK_UP; + var VK_RIGHT = KeyEvent.VK_RIGHT; + var VK_DOWN = KeyEvent.VK_DOWN; + } + if (typeof KeyEvent.VK_ENTER != "undefined") { + var VK_ENTER = KeyEvent.VK_ENTER; + } + if (typeof KeyEvent.VK_RED != "undefined") { + var VK_RED = KeyEvent.VK_RED; + var VK_GREEN = KeyEvent.VK_GREEN; + var VK_YELLOW = KeyEvent.VK_YELLOW; + var VK_BLUE = KeyEvent.VK_BLUE; + } + if (typeof KeyEvent.VK_PLAY != "undefined") { + var VK_PLAY = KeyEvent.VK_PLAY; + var VK_PAUSE = KeyEvent.VK_PAUSE; + var VK_STOP = KeyEvent.VK_STOP; + } + if (typeof KeyEvent.VK_BACK != "undefined") { + var VK_BACK = KeyEvent.VK_BACK; + } + if (typeof KeyEvent.VK_0 != "undefined") { + var VK_0 = KeyEvent.VK_0; + var VK_1 = KeyEvent.VK_1; + var VK_2 = KeyEvent.VK_2; + var VK_3 = KeyEvent.VK_3; + var VK_4 = KeyEvent.VK_4; + var VK_5 = KeyEvent.VK_5; + var VK_6 = KeyEvent.VK_6; + var VK_7 = KeyEvent.VK_7; + var VK_8 = KeyEvent.VK_8; + var VK_9 = KeyEvent.VK_9; + } +} +if (typeof VK_LEFT == "undefined") { + var VK_LEFT = 132; + var VK_UP = 130; + var VK_RIGHT = 133; + var VK_DOWN = 131; +} +if (typeof VK_ENTER == "undefined") { + var VK_ENTER = 13; +} +if (typeof VK_RED == "undefined") { + var VK_RED = 403; + var VK_GREEN = 404; + var VK_YELLOW = 502; + var VK_BLUE = 406; +} +if (typeof VK_PLAY == "undefined") { + var VK_PLAY = 19; + var VK_PAUSE = 19; + var VK_STOP = 413; +} +if (typeof VK_BACK == "undefined") { + var VK_BACK = 0xa6; +} +if (typeof VK_0 == "undefined") { + var VK_0 = 48; + var VK_1 = 49; + var VK_2 = 50; + var VK_3 = 51; + var VK_4 = 52; + var VK_5 = 53; + var VK_6 = 54; + var VK_7 = 55; + var VK_8 = 56; + var VK_9 = 57; +} + +var NEXT_KEYS = [39, 133, 131]; +var PREV_KEYS = [37, 132, 130]; +var ACTION_KEYS = [13, 32]; + +if (typeof KeyEvent != "undefined") { + if (typeof KeyEvent.VK_LEFT != "undefined") { + PREV_KEYS.push(KeyEvent.VK_LEFT); + PREV_KEYS.push(KeyEvent.VK_UP); + NEXT_KEYS.push(KeyEvent.VK_RIGHT); + NEXT_KEYS.push(KeyEvent.VK_DOWN); + } + if (typeof KeyEvent.VK_ENTER != "undefined") { + ACTION_KEYS.push(KeyEvent.VK_ENTER); + } +} \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/ui.js b/tests/wpt/web-platform-tests/tools/wave/www/lib/ui.js new file mode 100644 index 00000000000..684ed18009e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/ui.js @@ -0,0 +1,97 @@ +const UI = { + createElement: config => { + if (!config) return; + const elementType = config.element || "div"; + const element = document.createElement(elementType); + + Object.keys(config).forEach(property => { + const value = config[property]; + switch (property.toLowerCase()) { + case "id": + case "src": + case "style": + case "placeholder": + case "title": + case "accept": + element.setAttribute(property, value); + return; + case "classname": + element.setAttribute("class", value); + return; + case "colspan": + element.setAttribute("colspan", value); + return; + case "text": + element.innerText = value; + return; + case "value": + element.value = value; + return; + case "html": + element.innerHTML = value; + return; + case "onclick": + element.onclick = value.bind(element); + return; + case "onchange": + element.onchange = value.bind(element); + return; + case "onkeydown": + element.onkeydown = value.bind(element); + return; + case "onkeyup": + element.onkeyup = value.bind(element); + return; + case "type": + if (elementType === "input") element.setAttribute("type", value); + return; + case "children": + if (value instanceof Array) { + value.forEach(child => { + const childElement = + child instanceof Element ? child : UI.createElement(child); + if (!childElement) return; + element.appendChild(childElement); + }); + } else { + const child = value; + const childElement = + child instanceof Element ? child : UI.createElement(child); + if (!childElement) return; + element.appendChild(childElement); + element.appendChild(childElement); + } + return; + case "disabled": + if (value) element.setAttribute("disabled", true); + return; + case "checked": + if (value) element.setAttribute("checked", true); + return; + } + }); + return element; + }, + getElement: id => { + return document.getElementById(id); + }, + getRoot: () => { + return document.getElementsByTagName("body")[0]; + }, + scrollPositions: {}, + saveScrollPosition: elementId => { + let scrollElement = UI.getElement(elementId); + if (!scrollElement) return; + UI.scrollPositions[elementId] = { + scrollLeft: scrollElement.scrollLeft, + scrollRight: scrollElement.scrollRight + }; + }, + loadScrollPosition: elementId => { + let scrollElement = UI.getElement(elementId); + if (!scrollElement) return; + if (!UI.scrollPositions[elementId]) return; + scrollElement.scrollLeft = UI.scrollPositions[elementId].scrollLeft; + scrollElement.scrollRight = UI.scrollPositions[elementId].scrollRight; + } +}; diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/utils.js b/tests/wpt/web-platform-tests/tools/wave/www/lib/utils.js new file mode 100644 index 00000000000..d84a2cb69c4 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/utils.js @@ -0,0 +1,57 @@ +const utils = { + parseQuery: queryString => { + if (queryString.indexOf("?") === -1) return {}; + queryString = queryString.split("?")[1]; + const query = {}; + for (let part of queryString.split("&")) { + const keyValue = part.split("="); + query[keyValue[0]] = keyValue[1] ? keyValue[1] : null; + } + return query; + }, + percent: (count, total) => { + const percent = Math.floor((count / total) * 10000) / 100; + if (!percent) { + return 0; + } + return percent; + }, + saveBlobAsFile: (blob, filename) => { + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.style.display = "none"; + document.body.appendChild(a); + a.href = url; + a.download = filename; + a.click(); + document.body.removeChild(a); + }, + millisToTimeString(totalMilliseconds) { + let milliseconds = (totalMilliseconds % 1000) + ""; + milliseconds = milliseconds.padStart(3, "0"); + let seconds = (Math.floor(totalMilliseconds / 1000) % 60) + ""; + seconds = seconds.padStart(2, "0"); + let minutes = (Math.floor(totalMilliseconds / 60000) % 60) + ""; + minutes = minutes.padStart(2, "0"); + let hours = Math.floor(totalMilliseconds / 3600000) + ""; + hours = hours.padStart(2, "0"); + return `${hours}:${minutes}:${seconds}`; + }, + getBrowserIcon(browser) { + switch (browser.toLowerCase()) { + case "firefox": + return "fab fa-firefox"; + case "edge": + return "fab fa-edge"; + case "chrome": + case "chromium": + return "fab fa-chrome"; + case "safari": + case "webkit": + return "fab fa-safari"; + } + }, + copyObject(object) { + return JSON.parse(JSON.stringify(object)); + } +}; diff --git a/tests/wpt/web-platform-tests/tools/wave/www/lib/wave-service.js b/tests/wpt/web-platform-tests/tools/wave/www/lib/wave-service.js new file mode 100644 index 00000000000..e420290ebc6 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/lib/wave-service.js @@ -0,0 +1,674 @@ +function sendRequest(method, uri, headers, data, onSuccess, onError) { + var xhr = new XMLHttpRequest(); + xhr.onload = function() { + if (xhr.status === 200) { + onSuccess(xhr.response); + } else { + if (onError) onError(xhr.status, xhr.response); + } + }; + xhr.onerror = function() { + if (onError) onError(); + }; + xhr.open(method, WaveService.uriPrefix + uri, true); + for (var header in headers) { + xhr.setRequestHeader(header, headers[header]); + } + xhr.send(data); + return xhr; +} + +var WEB_ROOT = "{{WEB_ROOT}}" +var HTTP_PORT = "{{HTTP_PORT}}" +var HTTPS_PORT = "{{HTTPS_PORT}}" +var OPEN = "open"; +var CLOSED = "closed"; + +var WaveService = { + uriPrefix: WEB_ROOT, + socket: { + state: CLOSED, + onMessage: function() {}, + onOpen: function() {}, + onClose: function() {}, + send: function() {}, + close: function() {}, + onStateChange: function() {} + }, + // SESSIONS API + createSession: function(configuration, onSuccess, onError) { + var data = JSON.stringify({ + tests: configuration.tests, + types: configuration.types, + timeouts: configuration.timeouts, + reference_tokens: configuration.referenceTokens, + expiration_date: configuration.expirationDate, + labels: configuration.labels + }); + sendRequest( + "POST", + "api/sessions", + { "Content-Type": "application/json" }, + data, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.token); + }, + onError + ); + }, + readSession: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/sessions/" + token, + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess({ + token: jsonObject.token, + tests: jsonObject.tests, + types: jsonObject.types, + userAgent: jsonObject.user_agent, + labels: jsonObject.labels, + timeouts: jsonObject.timeouts, + browser: jsonObject.browser, + isPublic: jsonObject.is_public, + referenceTokens: jsonObject.reference_tokens, + webhookUrls: jsonObject.webhook_urls, + expirationDate: jsonObject.expiration_date + }); + }, + onError + ); + }, + readMultipleSessions: function(tokens, onSuccess, onError) { + var requestsLeft = tokens.length; + if (requestsLeft === 0) onSuccess([]); + var configurations = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + WaveService.readSession( + token, + function(configuration) { + requestsLeft--; + configurations.push(configuration); + if (requestsLeft === 0) onSuccess(configurations); + }, + function(status) { + if (status === 404) requestsLeft--; + if (status !== 404 && onError) onError(); + if (requestsLeft === 0) onSuccess(configurations); + } + ); + } + }, + readSessionStatus: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/sessions/" + token + "/status", + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess({ + token: jsonObject.token, + dateStarted: jsonObject.date_started, + dateFinished: jsonObject.date_finished, + testFilesCount: jsonObject.test_files_count, + testFilesCompleted: jsonObject.test_files_completed, + status: jsonObject.status + }); + }, + function() { + if (onError) onError(); + } + ); + }, + readMultipleSessionStatuses: function(tokens, onSuccess, onError) { + var requestsLeft = tokens.length; + if (requestsLeft === 0) onSuccess([]); + var statuses = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + WaveService.readSessionStatus( + token, + function(status) { + requestsLeft--; + statuses.push(status); + if (requestsLeft === 0) onSuccess(statuses); + }, + function() { + requestsLeft--; + if (requestsLeft === 0) onSuccess(statuses); + } + ); + } + }, + readPublicSessions: function(onSuccess, onError) { + sendRequest( + "GET", + "api/sessions/public", + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject); + }, + onError + ); + }, + updateSession: function(token, configuration, onSuccess, onError) { + var data = JSON.stringify({ + tests: configuration.tests, + types: configuration.types, + timeouts: configuration.timeouts, + reference_tokens: configuration.referenceTokens, + expiration_date: configuration.expirationDate + }); + sendRequest( + "PUT", + "api/sessions/" + token, + { "Content-Type": "application/json" }, + data, + function() { + onSuccess(); + }, + onError + ); + }, + updateLabels: function(token, labels, onSuccess, onError) { + var data = JSON.stringify({ labels: labels }); + sendRequest( + "PUT", + "api/sessions/" + token + "/labels", + { "Content-Type": "application/json" }, + data, + function() { + if (onSuccess) onSuccess(); + }, + onError + ); + }, + findToken: function(fragment, onSuccess, onError) { + sendRequest( + "GET", + "api/sessions/" + fragment, + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.token); + }, + onError + ); + }, + startSession: function(token, onSuccess, onError) { + sendRequest( + "POST", + "api/sessions/" + token + "/start", + null, + null, + function() { + onSuccess(); + }, + onError + ); + }, + pauseSession: function(token, onSuccess, onError) { + sendRequest( + "POST", + "api/sessions/" + token + "/pause", + null, + null, + function() { + onSuccess(); + }, + onError + ); + }, + stopSession: function(token, onSuccess, onError) { + sendRequest( + "POST", + "api/sessions/" + token + "/stop", + null, + null, + function() { + onSuccess(); + }, + onError + ); + }, + resumeSession: function(token, resumeToken, onSuccess, onError) { + var data = JSON.stringify({ resume_token: resumeToken }); + sendRequest( + "POST", + "api/sessions/" + token + "/resume", + { "Content-Type": "application/json" }, + data, + function() { + if (onSuccess) onSuccess(); + }, + function(response) { + if (onError) onError(response); + } + ); + }, + deleteSession: function(token, onSuccess, onError) { + sendRequest( + "DELETE", + "api/sessions/" + token, + null, + null, + function() { + onSuccess(); + }, + onError + ); + }, + + // TESTS API + readNextTest: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/tests/" + token + "/next", + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.next_test); + }, + onError + ); + }, + readLastCompletedTests: function(token, resultTypes, onSuccess, onError) { + var status = ""; + if (resultTypes) { + for (var i = 0; i < resultTypes.length; i++) { + var type = resultTypes[i]; + status += type + ","; + } + } + sendRequest( + "GET", + "api/tests/" + token + "/last_completed?status=" + status, + null, + null, + function(response) { + var tests = JSON.parse(response); + var parsedTests = []; + for (var status in tests) { + for (var i = 0; i < tests[status].length; i++) { + var path = tests[status][i]; + parsedTests.push({ path: path, status: status }); + } + } + onSuccess(parsedTests); + }, + onError + ); + }, + readMalfunctioningTests: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/tests/" + token + "/malfunctioning", + null, + null, + function(response) { + var tests = JSON.parse(response); + onSuccess(tests); + }, + function(response) { + var errorMessage = JSON.parse(response).error; + onError(errorMessage); + } + ); + }, + updateMalfunctioningTests: function( + token, + malfunctioningTests, + onSuccess, + onError + ) { + var data = JSON.stringify(malfunctioningTests); + sendRequest( + "PUT", + "api/tests/" + token + "/malfunctioning", + { "Content-Type": "application/json" }, + data, + function() { + onSuccess(); + }, + function(response) { + var errorMessage = JSON.parse(response).error; + onError(errorMessage); + } + ); + }, + readAvailableApis: function(onSuccess, onError) { + sendRequest( + "GET", + "api/tests/apis", + null, + null, + function(response) { + var apis = JSON.parse(response); + onSuccess(apis); + }, + function(response) { + if(!onError) return; + var errorMessage = JSON.parse(response).error; + onError(errorMessage); + } + ); + }, + + // RESULTS API + createResult: function(token, result, onSuccess, onError) { + sendRequest( + "POST", + "api/results/" + token, + { "Content-Type": "application/json" }, + JSON.stringify(result), + function() { + onSuccess(); + }, + onError + ); + }, + readResults: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/results/" + token, + null, + null, + function(response) { + onSuccess(JSON.parse(response)); + }, + onError + ); + }, + readResultsCompact: function(token, onSuccess, onError) { + sendRequest( + "GET", + "api/results/" + token + "/compact", + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject); + }, + onError + ); + }, + readResultComparison: function(tokens, onSuccess, onError) { + var comparison = {}; + var fetchComplete = function(results) { + comparison.total = {}; + for (var i = 0; i < results.length; i++) { + var result = results[i]; + var token = result.token; + comparison[token] = {}; + for (var api in result) { + if (api === "token") continue; + comparison[token][api] = result[api].pass; + if (!comparison.total[api]) { + var total = 0; + for (var status in result[api]) { + total = total + result[api][status]; + } + comparison.total[api] = total; + } + } + } + onSuccess(comparison); + }; + var requestsLeft = tokens.length; + if (requestsLeft === 0) onSuccess([]); + var results = []; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + (function(token) { + WaveService.readResultsCompact( + token, + function(result) { + requestsLeft--; + result.token = token; + results.push(result); + if (requestsLeft === 0) fetchComplete(results); + }, + function(responseStatus) { + if (responseStatus === 404) requestsLeft--; + if (status !== 404 && onError) onError(); + if (requestsLeft === 0) fetchComplete(results); + } + ); + })(token); + } + }, + downloadResults: function(token) { + location.href = "api/results/" + token + "/export"; + }, + downloadApiResult: function(token, api) { + location.href = "api/results/" + token + "/" + api + "/json"; + }, + downloadAllApiResults: function(token, api) { + location.href = "api/results/" + token + "/json"; + }, + downloadReport: function(token, api) { + location.href = "api/results/" + token + "/" + api + "/report"; + }, + importResults: function(data, onSuccess, onError) { + sendRequest( + "POST", + "api/results/import", + { "Content-Type": "application/octet-stream" }, + data, + function(response) { + var token = JSON.parse(response).token; + onSuccess(token); + }, + function(status, response) { + var errorMessage; + if (status === 500) { + errorMessage = "Internal server error."; + } else { + errorMessage = JSON.parse(response).error; + } + onError(errorMessage); + } + ); + }, + readResultsConfig: function(onSuccess, onError) { + sendRequest( + "GET", + "api/results/config", + null, + null, + function(response) { + var config = JSON.parse(response); + onSuccess({ + importEnabled: config.import_enabled, + reportsEnabled: config.reports_enabled + }); + }, + onError + ); + }, + readReportUri: function(token, api, onSuccess, onError) { + sendRequest( + "GET", + "api/results/" + token + "/" + api + "/reporturl", + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.uri); + }, + onError + ); + }, + downloadMultiReport: function(tokens, api) { + location.href = + "api/results/" + api + "/report?tokens=" + tokens.join(","); + }, + readMultiReportUri: function(tokens, api, onSuccess, onError) { + sendRequest( + "GET", + "api/results/" + api + "/reporturl?tokens=" + tokens.join(","), + null, + null, + function(response) { + var jsonObject = JSON.parse(response); + onSuccess(jsonObject.uri); + }, + onError + ); + }, + downloadResultsOverview: function(token) { + location.href = "api/results/" + token + "/overview"; + }, + + // UTILITY + addRecentSession: function(token) { + if (!token) return; + var state = WaveService.getState(); + if (!state.recent_sessions) state.recent_sessions = []; + if (state.recent_sessions.indexOf(token) !== -1) return; + state.recent_sessions.unshift(token); + WaveService.setState(state); + }, + addRecentSessions: function(tokens) { + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + WaveService.addRecentSession(token); + } + }, + getPinnedSessions: function() { + var state = WaveService.getState(); + if (!state || !state.pinned_sessions) return []; + return state.pinned_sessions; + }, + addPinnedSession: function(token) { + if (!token) return; + var state = WaveService.getState(); + if (!state.pinned_sessions) state.pinned_sessions = []; + if (state.pinned_sessions.indexOf(token) !== -1) return; + state.pinned_sessions.unshift(token); + WaveService.setState(state); + }, + getRecentSessions: function() { + var state = WaveService.getState(); + if (!state || !state.recent_sessions) return []; + return state.recent_sessions; + }, + setRecentSessions: function(sessionTokens) { + var state = WaveService.getState(); + state.recent_sessions = sessionTokens; + WaveService.setState(state); + }, + removePinnedSession: function(token) { + if (!token) return; + var state = WaveService.getState(); + if (!state.pinned_sessions) return; + var index = state.pinned_sessions.indexOf(token); + if (index === -1) return; + state.pinned_sessions.splice(index, 1); + WaveService.setState(state); + }, + removeRecentSession: function(token) { + var state = WaveService.getState(); + if (!state.recent_sessions) return; + var index = state.recent_sessions.indexOf(token); + if (index === -1) return; + state.recent_sessions.splice(index, 1); + WaveService.setState(state); + }, + getState: function() { + if (!window.localStorage) return null; + var storage = window.localStorage; + var state = JSON.parse(storage.getItem("wave")); + if (!state) return {}; + return state; + }, + setState: function(state) { + if (!window.localStorage) return null; + var storage = window.localStorage; + storage.setItem("wave", JSON.stringify(state)); + }, + connectWebSocket: function(token) { + var protocol; + if (location.protocol === "https:") { + protocol = "wss"; + } else { + protocol = "ws"; + } + var url = protocol + "://" + location.host; + console.log("Connecting web socket to" + url); + var webSocket = new WebSocket(url); + webSocket.onmessage = function(message) { + WaveService.socket.onMessage(JSON.parse(message.data)); + }; + webSocket.onclose = function() { + WaveService.socket.state = CLOSED; + WaveService.socket.onStateChange(CLOSED); + WaveService.socket.onClose(); + }; + webSocket.onopen = function() { + WaveService.socket.state = OPEN; + WaveService.socket.onStateChange(OPEN); + WaveService.socket.onOpen(); + webSocket.send(JSON.stringify({ token: token })); + }; + WaveService.socket.send = function(message) { + webSocket.send(message); + }; + WaveService.socket.close = function() { + webSocket.close(); + }; + }, + connectHttpPolling: function(token) { + var uniqueId = new Date().getTime() + var poll = function() { + var request = sendRequest( + "GET", + "api/sessions/" + token + "/events?id=" + uniqueId, + null, + null, + function(response) { + if (WaveService.socket.state === OPEN) poll(); + WaveService.socket.onMessage(JSON.parse(response)); + }, + function() { + if (WaveService.socket.state === OPEN) setTimeout(poll, 1000); + } + ); + WaveService.socket.close = function() { + request.abort(); + WaveService.socket.state = CLOSED; + WaveService.socket.onStateChange(CLOSED); + WaveService.socket.onClose(); + }; + }; + poll(); + WaveService.socket.onOpen(); + WaveService.socket.state = OPEN; + WaveService.socket.onStateChange(OPEN); + }, + connect: function(token) { + if (window.WebSocket) { + WaveService.connectWebSocket(token); + } else { + WaveService.connectHttpPolling(token); + } + }, + onMessage: function(callback) { + WaveService.socket.onMessage = callback; + }, + isConnected: function() { + return WaveService.socket.state === OPEN; + }, + openSession: function(token) { + location.href = "/results.html?token=" + token; + } +}; diff --git a/tests/wpt/web-platform-tests/tools/wave/www/newsession.html b/tests/wpt/web-platform-tests/tools/wave/www/newsession.html new file mode 100644 index 00000000000..0ff308c8b4b --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/newsession.html @@ -0,0 +1,257 @@ + + + + + New Session - Web Platform Test Runner + + + + + + + + +
+ + +
+
+
+
+

+ Scan QR Code OR visit + + and follow instructions +

+
+ + +
+ +
(Alternatively to start the test you can just press Return)
+ +
+

Details

+
+
Token:
+
+
+
+
User Agent:
+
+
+
+
Test Types:
+
+
+
+
Total Test Files:
+
+
+
+
Reference Tokens:
+
+
+
+
Test Timeouts:
+
+
+
+
Test Paths:
+
+
+
+
+
+
+ + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/next.html b/tests/wpt/web-platform-tests/tools/wave/www/next.html new file mode 100644 index 00000000000..277f4afed67 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/next.html @@ -0,0 +1,45 @@ + + + + + + +
+ + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/overview.html b/tests/wpt/web-platform-tests/tools/wave/www/overview.html new file mode 100644 index 00000000000..cabb158711a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/overview.html @@ -0,0 +1,1315 @@ + + + + + + Overview - Web Platform Test + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/pause.html b/tests/wpt/web-platform-tests/tools/wave/www/pause.html new file mode 100644 index 00000000000..a561968e112 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/pause.html @@ -0,0 +1,225 @@ + + + + + Session Paused - Web Platform Test Runner + + + + + + + + +
+ + +
+
+
+ + +
+
(Alternatively to resume the test you can just press Return)
+
+

Details

+
+
Token:
+
+
+
+
User Agent:
+
+
+
+
Test Types:
+
+
+
+
Total Test Files:
+
+
+
+
Reference Tokens:
+
+
+
+
Test Timeouts:
+
+
+
+
Test Paths:
+
+
+
+
+
+ + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/res/spinner-solid.svg b/tests/wpt/web-platform-tests/tools/wave/www/res/spinner-solid.svg new file mode 100644 index 00000000000..f795980b3d5 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/res/spinner-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/tools/wave/www/res/wavelogo_2016.jpg b/tests/wpt/web-platform-tests/tools/wave/www/res/wavelogo_2016.jpg new file mode 100644 index 00000000000..38814095971 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/res/wavelogo_2016.jpg differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/results.html b/tests/wpt/web-platform-tests/tools/wave/www/results.html new file mode 100644 index 00000000000..839ce05590c --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/results.html @@ -0,0 +1,1545 @@ + + + + + + Session Results - Web Platform Test + + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/submitresult.html b/tests/wpt/web-platform-tests/tools/wave/www/submitresult.html new file mode 100644 index 00000000000..000c5a1208a --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/submitresult.html @@ -0,0 +1,64 @@ + + + + + Web Platform Tests + + + + +
+ + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.eot b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.eot new file mode 100644 index 00000000000..da7bd5eb705 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.eot differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.svg b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.svg new file mode 100644 index 00000000000..caa8cc43ca7 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.svg @@ -0,0 +1,3296 @@ + + + + +Created by FontForge 20190112 at Tue Feb 12 10:24:59 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.ttf b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.ttf new file mode 100644 index 00000000000..5f72e9127ff Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.ttf differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff new file mode 100644 index 00000000000..c64755a5256 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff2 b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff2 new file mode 100644 index 00000000000..b5a956765bd Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-brands-400.woff2 differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.eot b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.eot new file mode 100644 index 00000000000..55085ca95d1 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.eot differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.svg b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.svg new file mode 100644 index 00000000000..bba54466b91 --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.svg @@ -0,0 +1,799 @@ + + + + +Created by FontForge 20190112 at Tue Feb 12 10:24:59 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.ttf b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.ttf new file mode 100644 index 00000000000..a309313d5fb Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.ttf differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff new file mode 100644 index 00000000000..2578261897a Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff2 b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff2 new file mode 100644 index 00000000000..3ef9c3edb06 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-regular-400.woff2 differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.eot b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.eot new file mode 100644 index 00000000000..68c010a8628 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.eot differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.svg b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.svg new file mode 100644 index 00000000000..4ef85aa379e --- /dev/null +++ b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.svg @@ -0,0 +1,4516 @@ + + + + +Created by FontForge 20190112 at Tue Feb 12 10:24:59 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.ttf b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.ttf new file mode 100644 index 00000000000..7ece3282a4f Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.ttf differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff new file mode 100644 index 00000000000..a892a7a9c15 Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff differ diff --git a/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff2 b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff2 new file mode 100644 index 00000000000..71b07ce028e Binary files /dev/null and b/tests/wpt/web-platform-tests/tools/wave/www/webfonts/fa-solid-900.woff2 differ diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py index 086560b6a87..445063d55b7 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/chromium.py @@ -1,5 +1,6 @@ import json import time +import six from collections import defaultdict from mozlog.formatters import base @@ -8,6 +9,12 @@ from mozlog.formatters import base class ChromiumFormatter(base.BaseFormatter): """Formatter to produce results matching the Chromium JSON Test Results format. https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md + + Notably, each test has an "artifacts" field that is a dict consisting of + "log": a list of strings (one per subtest + one for harness status, see + _append_test_message for the format) + "screenshots": a list of strings in the format of "url: base64" + """ def __init__(self): @@ -24,9 +31,9 @@ class ChromiumFormatter(base.BaseFormatter): # the trie and the leaf contains the dict of per-test data. self.tests = {} - # Message dictionary, keyed by test name. Value is a concatenation of - # the subtest messages for this test. - self.messages = defaultdict(str) + # Message dictionary, keyed by test name. Value is a list of strings: + # see _append_test_message for the format. + self.messages = defaultdict(list) # List of tests that have failing subtests. self.tests_with_subtest_fails = set() @@ -40,20 +47,11 @@ class ChromiumFormatter(base.BaseFormatter): :param str expected: the expected subtest statuses :param str message: the string to append to the message for this test - Here's an example of a message: - [TIMEOUT expected FAIL] Test Name foo: assert_equals: expected 1 but got 2 + Example: + [subtest foo] [FAIL expected PASS] message """ - if not message: - return - # Add the prefix, with the test status and subtest name (if available) - prefix = "[%s" % status - if expected and status not in expected: - prefix += " expected %s] " % expected - else: - prefix += "] " - if subtest: - prefix += "%s: " % subtest - self.messages[test] += prefix + message + "\n" + self.messages[test].append("[%s] [%s expected %s] %s" % + (subtest, status, expected, message)) def _append_artifact(self, cur_dict, artifact_name, artifact_value): """ @@ -62,21 +60,22 @@ class ChromiumFormatter(base.BaseFormatter): :param str artifact_name: the name of the artifact :param str artifact_value: the value of the artifact """ + assert isinstance(artifact_value, six.string_types), "artifact_value must be a str" if "artifacts" not in cur_dict.keys(): - cur_dict["artifacts"] = {} - # Artifacts are all expected to be lists, so even though we only have a - # single |artifact_value| we still put it in a list. - cur_dict["artifacts"][artifact_name] = [artifact_value] + cur_dict["artifacts"] = defaultdict(list) + cur_dict["artifacts"][artifact_name].append(artifact_value) - def _store_test_result(self, name, actual, expected, message, wpt_actual, subtest_failure): + def _store_test_result(self, name, actual, expected, messages, wpt_actual, + subtest_failure, reftest_screenshots): """ Stores the result of a single test in |self.tests| :param str name: name of the test. :param str actual: actual status of the test. :param str expected: expected statuses of the test. - :param str message: test output, such as status, subtest, errors etc. + :param list messages: a list of test messages. :param str wpt_actual: actual status reported by wpt, may differ from |actual|. - :param bool subtest_failure: whether this test failed because of subtests + :param bool subtest_failure: whether this test failed because of subtests. + :param Optional[list] reftest_screenshots: see executors/base.py for definition. """ # The test name can contain a leading / which will produce an empty # string in the first position of the list returned by split. We use @@ -91,9 +90,17 @@ class ChromiumFormatter(base.BaseFormatter): self._append_artifact(cur_dict, "wpt_subtest_failure", "true") if wpt_actual != actual: self._append_artifact(cur_dict, "wpt_actual_status", wpt_actual) - if message != "": + for message in messages: self._append_artifact(cur_dict, "log", message) + # Store screenshots (if any). + for item in reftest_screenshots or []: + if not isinstance(item, dict): + # Skip the relation string. + continue + data = "%s: %s" % (item["url"], item["screenshot"]) + self._append_artifact(cur_dict, "screenshots", data) + # Figure out if there was a regression or unexpected status. This only # happens for tests that were run if actual != "SKIP": @@ -172,13 +179,14 @@ class ChromiumFormatter(base.BaseFormatter): is_unexpected = actual_status not in expected_statuses if is_unexpected and test_name not in self.tests_with_subtest_fails: self.tests_with_subtest_fails.add(test_name) - if "message" in data: - self._append_test_message(test_name, data["subtest"], actual_status, expected_statuses, data["message"]) + self._append_test_message(test_name, data.get("subtest", ""), + actual_status, expected_statuses, + data.get("message", "")) def test_end(self, data): test_name = data["test"] - # Save the status reported by WPT since we might change it when reporting - # to Chromium. + # Save the status reported by WPT since we might change it when + # reporting to Chromium. wpt_actual_status = data["status"] actual_status = self._map_status_name(wpt_actual_status) expected_statuses = self._get_expected_status_from_data(actual_status, data) @@ -193,12 +201,16 @@ class ChromiumFormatter(base.BaseFormatter): if actual_status == "PASS": actual_status = "FAIL" - if "message" in data: - self._append_test_message(test_name, None, actual_status, - expected_statuses, data["message"]) - self._store_test_result(test_name, actual_status, expected_statuses, - self.messages[test_name], wpt_actual_status, - subtest_failure) + self._append_test_message(test_name, "", + actual_status, expected_statuses, + data.get("message", "")) + self._store_test_result(test_name, + actual_status, + expected_statuses, + self.messages[test_name], + wpt_actual_status, + subtest_failure, + data.get("extra", {}).get("reftest_screenshots")) # Remove the test from messages dict to avoid accumulating too many. self.messages.pop(test_name) diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py index 2a5d3e79280..efff5f02a48 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/formatters/tests/test_chromium.py @@ -139,7 +139,7 @@ def test_subtest_messages(capfd): message="t1_b_message") logger.test_end("t1", status="PASS", expected="PASS") logger.test_start("t2") - # Currently, subtests with empty messages will be ignored + # Subtests with empty messages should not be ignored. logger.test_status("t2", status="PASS", subtest="t2_a") # A test-level message will also be appended logger.test_end("t2", status="TIMEOUT", expected="PASS", @@ -157,11 +157,17 @@ def test_subtest_messages(capfd): output_json = json.load(output) t1_artifacts = output_json["tests"]["t1"]["artifacts"] - assert t1_artifacts["log"] == ["[FAIL expected PASS] t1_a: t1_a_message\n" - "[PASS] t1_b: t1_b_message\n"] + assert t1_artifacts["log"] == [ + "[t1_a] [FAIL expected PASS] t1_a_message", + "[t1_b] [PASS expected PASS] t1_b_message", + "[] [FAIL expected PASS] ", + ] assert t1_artifacts["wpt_subtest_failure"] == ["true"] t2_artifacts = output_json["tests"]["t2"]["artifacts"] - assert t2_artifacts["log"] == ["[TIMEOUT expected PASS] t2_message\n"] + assert t2_artifacts["log"] == [ + "[t2_a] [PASS expected PASS] ", + "[] [TIMEOUT expected PASS] t2_message", + ] assert "wpt_subtest_failure" not in t2_artifacts.keys() @@ -204,9 +210,12 @@ def test_subtest_failure(capfd): test_obj = output_json["tests"]["t1"] t1_artifacts = test_obj["artifacts"] - assert t1_artifacts["log"] == ["[FAIL expected PASS] t1_a: t1_a_message\n" - "[PASS] t1_b: t1_b_message\n" - "[TIMEOUT expected PASS] t1_c: t1_c_message\n"] + assert t1_artifacts["log"] == [ + "[t1_a] [FAIL expected PASS] t1_a_message", + "[t1_b] [PASS expected PASS] t1_b_message", + "[t1_c] [TIMEOUT expected PASS] t1_c_message", + "[] [FAIL expected PASS] ", + ] assert t1_artifacts["wpt_subtest_failure"] == ["true"] # The status of the test in the output is a failure because subtests failed, # despite the harness reporting that the test passed. But the harness status @@ -258,9 +267,12 @@ def test_expected_subtest_failure(capfd): test_obj = output_json["tests"]["t1"] t1_log = test_obj["artifacts"]["log"] - assert t1_log == ["[FAIL] t1_a: t1_a_message\n" - "[PASS] t1_b: t1_b_message\n" - "[TIMEOUT] t1_c: t1_c_message\n"] + assert t1_log == [ + "[t1_a] [FAIL expected FAIL] t1_a_message", + "[t1_b] [PASS expected PASS] t1_b_message", + "[t1_c] [TIMEOUT expected TIMEOUT] t1_c_message", + "[] [PASS expected PASS] ", + ] # The status of the test in the output is a pass because the subtest # failures were all expected. assert test_obj["actual"] == "PASS" @@ -303,7 +315,10 @@ def test_unexpected_subtest_pass(capfd): test_obj = output_json["tests"]["t1"] t1_artifacts = test_obj["artifacts"] - assert t1_artifacts["log"] == ["[PASS expected FAIL] t1_a: t1_a_message\n"] + assert t1_artifacts["log"] == [ + "[t1_a] [PASS expected FAIL] t1_a_message", + "[] [FAIL expected PASS] ", + ] assert t1_artifacts["wpt_subtest_failure"] == ["true"] # Since the subtest status is unexpected, we fail the test. But we report # wpt_actual_status as an artifact @@ -518,3 +533,40 @@ def test_known_intermittent_empty(capfd): # anywhere. assert test_obj["actual"] == "PASS" assert test_obj["expected"] == "PASS" + + +def test_reftest_screenshots(capfd): + # reftest_screenshots, if present, should be plumbed into artifacts. + + # Set up the handler. + output = StringIO() + logger = structuredlog.StructuredLogger("test_a") + logger.add_handler(handlers.StreamHandler(output, ChromiumFormatter())) + + # Run a reftest with reftest_screenshots. + logger.suite_start(["t1"], run_info={}, time=123) + logger.test_start("t1") + logger.test_end("t1", status="FAIL", expected="PASS", extra={ + "reftest_screenshots": [ + {"url": "foo.html", "hash": "HASH1", "screenshot": "DATA1"}, + "!=", + {"url": "foo-ref.html", "hash": "HASH2", "screenshot": "DATA2"}, + ] + }) + logger.suite_end() + + # check nothing got output to stdout/stderr + # (note that mozlog outputs exceptions during handling to stderr!) + captured = capfd.readouterr() + assert captured.out == "" + assert captured.err == "" + + # check the actual output of the formatter + output.seek(0) + output_json = json.load(output) + + test_obj = output_json["tests"]["t1"] + assert test_obj["artifacts"]["screenshots"] == [ + "foo.html: DATA1", + "foo-ref.html: DATA2", + ] diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.tentative.html new file mode 100644 index 00000000000..d0920497d94 --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none-skip.tentative.html @@ -0,0 +1,19 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none.tentative.html b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none.tentative.html new file mode 100644 index 00000000000..48c75937ead --- /dev/null +++ b/tests/wpt/web-platform-tests/trusted-types/TrustedTypePolicyFactory-createPolicy-cspTests-none.tentative.html @@ -0,0 +1,19 @@ + + + + + + + diff --git a/tests/wpt/web-platform-tests/web-locks/clientids.tentative.https.html b/tests/wpt/web-platform-tests/web-locks/clientids.tentative.https.html index 9ce4c4e9d18..02dabfa606a 100644 --- a/tests/wpt/web-platform-tests/web-locks/clientids.tentative.https.html +++ b/tests/wpt/web-platform-tests/web-locks/clientids.tentative.https.html @@ -17,6 +17,7 @@ function nextMessage() { } promise_test(async t => { + assert_implements(navigator.locks); const iframe_url = 'resources/sw-controlled-iframe.html'; // Register a service worker that will control an iframe. diff --git a/tests/wpt/web-platform-tests/web-locks/frames.tentative.https.html b/tests/wpt/web-platform-tests/web-locks/frames.tentative.https.html index 7d8383cffc1..84760f2f405 100644 --- a/tests/wpt/web-platform-tests/web-locks/frames.tentative.https.html +++ b/tests/wpt/web-platform-tests/web-locks/frames.tentative.https.html @@ -10,6 +10,7 @@ 'use strict'; promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); const frame = await iframe('resources/iframe.html'); @@ -25,6 +26,7 @@ promise_test(async t => { }, 'Window and Frame - shared mode'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); const frame = await iframe('resources/iframe.html'); @@ -54,6 +56,7 @@ promise_test(async t => { }, 'Window and Frame - exclusive mode'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); const frame1 = await iframe('resources/iframe.html'); @@ -86,6 +89,7 @@ promise_test(async t => { }, 'Frame and Frame - exclusive mode'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); const frame = await iframe('resources/iframe.html'); @@ -114,6 +118,7 @@ promise_test(async t => { }, 'Terminated Frame with held lock'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); const frame = await iframe('resources/iframe.html'); @@ -142,6 +147,7 @@ promise_test(async t => { }, 'Navigated Frame with held lock'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); // frame1 requests and holds res - should be granted immediately. @@ -190,6 +196,7 @@ promise_test(async t => { }, 'Navigated Frame with pending request'); promise_test(async t => { + assert_implements(navigator.locks); const res = uniqueName(t); // frame1 requests and holds res - should be granted immediately. diff --git a/tests/wpt/web-platform-tests/web-locks/query-ordering.tentative.https.html b/tests/wpt/web-platform-tests/web-locks/query-ordering.tentative.https.html index bbbee3880b7..172a1db87b7 100644 --- a/tests/wpt/web-platform-tests/web-locks/query-ordering.tentative.https.html +++ b/tests/wpt/web-platform-tests/web-locks/query-ordering.tentative.https.html @@ -42,6 +42,7 @@ function nextMessage() { // distinguishable client_ids (otherwise it would not be possible to // distinguish the requests and thus impossible to verify ordering). promise_test(async testCase => { + assert_implements(navigator.locks); const resourceName = uniqueName(testCase); // Set up clients. diff --git a/tests/wpt/web-platform-tests/web-locks/workers.tentative.https.html b/tests/wpt/web-platform-tests/web-locks/workers.tentative.https.html index 04af72c8ad0..f1f11c603a4 100644 --- a/tests/wpt/web-platform-tests/web-locks/workers.tentative.https.html +++ b/tests/wpt/web-platform-tests/web-locks/workers.tentative.https.html @@ -9,6 +9,7 @@ 'use strict'; promise_test(async t => { + assert_implements(navigator.locks); const worker = new Worker('resources/worker.js'); t.add_cleanup(() => { worker.terminate(); }); @@ -24,6 +25,7 @@ promise_test(async t => { }, 'Window and Worker - shared mode'); promise_test(async t => { + assert_implements(navigator.locks); const worker = new Worker('resources/worker.js'); t.add_cleanup(() => { worker.terminate(); }); @@ -55,6 +57,7 @@ promise_test(async t => { }, 'Window and Worker - exclusive mode'); promise_test(async t => { + assert_implements(navigator.locks); const worker1 = new Worker('resources/worker.js'); const worker2 = new Worker('resources/worker.js'); t.add_cleanup(() => { worker1.terminate(); worker2.terminate(); }); @@ -87,6 +90,7 @@ promise_test(async t => { }, 'Worker and Worker - exclusive mode'); promise_test(async t => { + assert_implements(navigator.locks); const worker = new Worker('resources/worker.js'); const res = 'exclusive resource 3'; diff --git a/tests/wpt/web-platform-tests/webgpu/common/constants.js b/tests/wpt/web-platform-tests/webgpu/common/constants.js deleted file mode 100644 index 69496b1b23b..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/constants.js +++ /dev/null @@ -1,302 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -// https://github.com/gpuweb/gpuweb/blob/0a48816412b5d08a5fb8b89005e019165a1a2c63/spec/index.bs -// tslint:disable:variable-name -// String enums -export let ExtensionName; - -(function (ExtensionName) { - ExtensionName["TextureCompressionBC"] = "texture-compression-bc"; -})(ExtensionName || (ExtensionName = {})); - -export let AddressMode; - -(function (AddressMode) { - AddressMode["ClampToEdge"] = "clamp-to-edge"; - AddressMode["Repeat"] = "repeat"; - AddressMode["MirrorRepeat"] = "mirror-repeat"; -})(AddressMode || (AddressMode = {})); - -export let BindingType; - -(function (BindingType) { - BindingType["UniformBuffer"] = "uniform-buffer"; - BindingType["StorageBuffer"] = "storage-buffer"; - BindingType["ReadonlyStorageBuffer"] = "readonly-storage-buffer"; - BindingType["Sampler"] = "sampler"; - BindingType["ComparisonSampler"] = "comparison-sampler"; - BindingType["SampledTexture"] = "sampled-texture"; - BindingType["ReadonlyStorageTexture"] = "readonly-storage-texture"; - BindingType["WriteonlyStorageTexture"] = "writeonly-storage-texture"; -})(BindingType || (BindingType = {})); - -export let BlendFactor; - -(function (BlendFactor) { - BlendFactor["Zero"] = "zero"; - BlendFactor["One"] = "one"; - BlendFactor["SrcColor"] = "src-color"; - BlendFactor["OneMinusSrcColor"] = "one-minus-src-color"; - BlendFactor["SrcAlpha"] = "src-alpha"; - BlendFactor["OneMinusSrcAlpha"] = "one-minus-src-alpha"; - BlendFactor["DstColor"] = "dst-color"; - BlendFactor["OneMinusDstColor"] = "one-minus-dst-color"; - BlendFactor["DstAlpha"] = "dst-alpha"; - BlendFactor["OneMinusDstAlpha"] = "one-minus-dst-alpha"; - BlendFactor["SrcAlphaSaturated"] = "src-alpha-saturated"; - BlendFactor["BlendColor"] = "blend-color"; - BlendFactor["OneMinusBlendColor"] = "one-minus-blend-color"; -})(BlendFactor || (BlendFactor = {})); - -export let BlendOperation; - -(function (BlendOperation) { - BlendOperation["Add"] = "add"; - BlendOperation["Subtract"] = "subtract"; - BlendOperation["ReverseSubtract"] = "reverse-subtract"; - BlendOperation["Min"] = "min"; - BlendOperation["Max"] = "max"; -})(BlendOperation || (BlendOperation = {})); - -export let CompareFunction; - -(function (CompareFunction) { - CompareFunction["Never"] = "never"; - CompareFunction["Less"] = "less"; - CompareFunction["Equal"] = "equal"; - CompareFunction["LessEqual"] = "less-equal"; - CompareFunction["Greater"] = "greater"; - CompareFunction["NotEqual"] = "not-equal"; - CompareFunction["GreaterEqual"] = "greater-equal"; - CompareFunction["Always"] = "always"; -})(CompareFunction || (CompareFunction = {})); - -export let CullMode; - -(function (CullMode) { - CullMode["None"] = "none"; - CullMode["Front"] = "front"; - CullMode["Back"] = "back"; -})(CullMode || (CullMode = {})); - -export let FilterMode; - -(function (FilterMode) { - FilterMode["Nearest"] = "nearest"; - FilterMode["Linear"] = "linear"; -})(FilterMode || (FilterMode = {})); - -export let FrontFace; - -(function (FrontFace) { - FrontFace["CCW"] = "ccw"; - FrontFace["CW"] = "cw"; -})(FrontFace || (FrontFace = {})); - -export let IndexFormat; - -(function (IndexFormat) { - IndexFormat["Uint16"] = "uint16"; - IndexFormat["Uint32"] = "uint32"; -})(IndexFormat || (IndexFormat = {})); - -export let InputStepMode; - -(function (InputStepMode) { - InputStepMode["Vertex"] = "vertex"; - InputStepMode["Instance"] = "instance"; -})(InputStepMode || (InputStepMode = {})); - -export let LoadOp; - -(function (LoadOp) { - LoadOp["Load"] = "load"; -})(LoadOp || (LoadOp = {})); - -export let PrimitiveTopology; - -(function (PrimitiveTopology) { - PrimitiveTopology["PointList"] = "point-list"; - PrimitiveTopology["LineList"] = "line-list"; - PrimitiveTopology["LineStrip"] = "line-strip"; - PrimitiveTopology["TriangleList"] = "triangle-list"; - PrimitiveTopology["TriangleStrip"] = "triangle-strip"; -})(PrimitiveTopology || (PrimitiveTopology = {})); - -export let StencilOperation; - -(function (StencilOperation) { - StencilOperation["Keep"] = "keep"; - StencilOperation["Zero"] = "zero"; - StencilOperation["Replace"] = "replace"; - StencilOperation["Invert"] = "invert"; - StencilOperation["IncrementClamp"] = "increment-clamp"; - StencilOperation["DecrementClamp"] = "decrement-clamp"; - StencilOperation["IncrementWrap"] = "increment-wrap"; - StencilOperation["DecrementWrap"] = "decrement-wrap"; -})(StencilOperation || (StencilOperation = {})); - -export let StoreOp; - -(function (StoreOp) { - StoreOp["Store"] = "store"; - StoreOp["Clear"] = "clear"; -})(StoreOp || (StoreOp = {})); - -export let TextureDimension; - -(function (TextureDimension) { - TextureDimension["E1d"] = "1d"; - TextureDimension["E2d"] = "2d"; - TextureDimension["E3d"] = "3d"; -})(TextureDimension || (TextureDimension = {})); - -export let TextureFormat; - -(function (TextureFormat) { - TextureFormat["R8Unorm"] = "r8unorm"; - TextureFormat["R8Snorm"] = "r8snorm"; - TextureFormat["R8Uint"] = "r8uint"; - TextureFormat["R8Sint"] = "r8sint"; - TextureFormat["R16Uint"] = "r16uint"; - TextureFormat["R16Sint"] = "r16sint"; - TextureFormat["R16Float"] = "r16float"; - TextureFormat["RG8Unorm"] = "rg8unorm"; - TextureFormat["RG8Snorm"] = "rg8snorm"; - TextureFormat["RG8Uint"] = "rg8uint"; - TextureFormat["RG8Sint"] = "rg8sint"; - TextureFormat["R32Uint"] = "r32uint"; - TextureFormat["R32Sint"] = "r32sint"; - TextureFormat["R32Float"] = "r32float"; - TextureFormat["RG16Uint"] = "rg16uint"; - TextureFormat["RG16Sint"] = "rg16sint"; - TextureFormat["RG16Float"] = "rg16float"; - TextureFormat["RGBA8Unorm"] = "rgba8unorm"; - TextureFormat["RGBA8UnormSRGB"] = "rgba8unorm-srgb"; - TextureFormat["RGBA8Snorm"] = "rgba8snorm"; - TextureFormat["RGBA8Uint"] = "rgba8uint"; - TextureFormat["RGBA8Sint"] = "rgba8sint"; - TextureFormat["BGRA8Unorm"] = "bgra8unorm"; - TextureFormat["BGRA8UnormSRGB"] = "bgra8unorm-srgb"; - TextureFormat["RGB10A2Unorm"] = "rgb10a2unorm"; - TextureFormat["RG11B10Float"] = "rg11b10float"; - TextureFormat["RG32Uint"] = "rg32uint"; - TextureFormat["RG32Sint"] = "rg32sint"; - TextureFormat["RG32Float"] = "rg32float"; - TextureFormat["RGBA16Uint"] = "rgba16uint"; - TextureFormat["RGBA16Sint"] = "rgba16sint"; - TextureFormat["RGBA16Float"] = "rgba16float"; - TextureFormat["RGBA32Uint"] = "rgba32uint"; - TextureFormat["RGBA32Sint"] = "rgba32sint"; - TextureFormat["RGBA32Float"] = "rgba32float"; - TextureFormat["Depth32Float"] = "depth32float"; - TextureFormat["Depth24Plus"] = "depth24plus"; - TextureFormat["Depth24PlusStencil8"] = "depth24plus-stencil8"; -})(TextureFormat || (TextureFormat = {})); - -export let TextureComponentType; - -(function (TextureComponentType) { - TextureComponentType["Float"] = "float"; - TextureComponentType["Sint"] = "sint"; - TextureComponentType["Uint"] = "uint"; -})(TextureComponentType || (TextureComponentType = {})); - -export let TextureViewDimension; - -(function (TextureViewDimension) { - TextureViewDimension["E1d"] = "1d"; - TextureViewDimension["E2d"] = "2d"; - TextureViewDimension["E2dArray"] = "2d-array"; - TextureViewDimension["Cube"] = "cube"; - TextureViewDimension["CubeArray"] = "cube-array"; - TextureViewDimension["E3d"] = "3d"; -})(TextureViewDimension || (TextureViewDimension = {})); - -export let VertexFormat; - -(function (VertexFormat) { - VertexFormat["Uchar2"] = "uchar2"; - VertexFormat["Uchar4"] = "uchar4"; - VertexFormat["Char2"] = "char2"; - VertexFormat["Char4"] = "char4"; - VertexFormat["Uchar2Norm"] = "uchar2norm"; - VertexFormat["Uchar4Norm"] = "uchar4norm"; - VertexFormat["Char2Norm"] = "char2norm"; - VertexFormat["Char4Norm"] = "char4norm"; - VertexFormat["Ushort2"] = "ushort2"; - VertexFormat["Ushort4"] = "ushort4"; - VertexFormat["Short2"] = "short2"; - VertexFormat["Short4"] = "short4"; - VertexFormat["Ushort2Norm"] = "ushort2norm"; - VertexFormat["Ushort4Norm"] = "ushort4norm"; - VertexFormat["Short2Norm"] = "short2norm"; - VertexFormat["Short4Norm"] = "short4norm"; - VertexFormat["Half2"] = "half2"; - VertexFormat["Half4"] = "half4"; - VertexFormat["Float"] = "float"; - VertexFormat["Float2"] = "float2"; - VertexFormat["Float3"] = "float3"; - VertexFormat["Float4"] = "float4"; - VertexFormat["Uint"] = "uint"; - VertexFormat["Uint2"] = "uint2"; - VertexFormat["Uint3"] = "uint3"; - VertexFormat["Uint4"] = "uint4"; - VertexFormat["Int"] = "int"; - VertexFormat["Int2"] = "int2"; - VertexFormat["Int3"] = "int3"; - VertexFormat["Int4"] = "int4"; -})(VertexFormat || (VertexFormat = {})); - -export let TextureAspect; // Bit fields - -(function (TextureAspect) { - TextureAspect["All"] = "all"; - TextureAspect["StencilOnly"] = "stencil-only"; - TextureAspect["DepthOnly"] = "depth-only"; -})(TextureAspect || (TextureAspect = {})); - -export let BufferUsage; - -(function (BufferUsage) { - BufferUsage[BufferUsage["MapRead"] = 1] = "MapRead"; - BufferUsage[BufferUsage["MapWrite"] = 2] = "MapWrite"; - BufferUsage[BufferUsage["CopySrc"] = 4] = "CopySrc"; - BufferUsage[BufferUsage["CopyDst"] = 8] = "CopyDst"; - BufferUsage[BufferUsage["Index"] = 16] = "Index"; - BufferUsage[BufferUsage["Vertex"] = 32] = "Vertex"; - BufferUsage[BufferUsage["Uniform"] = 64] = "Uniform"; - BufferUsage[BufferUsage["Storage"] = 128] = "Storage"; - BufferUsage[BufferUsage["Indirect"] = 256] = "Indirect"; -})(BufferUsage || (BufferUsage = {})); - -export let ColorWrite; - -(function (ColorWrite) { - ColorWrite[ColorWrite["Red"] = 1] = "Red"; - ColorWrite[ColorWrite["Green"] = 2] = "Green"; - ColorWrite[ColorWrite["Blue"] = 4] = "Blue"; - ColorWrite[ColorWrite["Alpha"] = 8] = "Alpha"; - ColorWrite[ColorWrite["All"] = 15] = "All"; -})(ColorWrite || (ColorWrite = {})); - -export let ShaderStage; - -(function (ShaderStage) { - ShaderStage[ShaderStage["Vertex"] = 1] = "Vertex"; - ShaderStage[ShaderStage["Fragment"] = 2] = "Fragment"; - ShaderStage[ShaderStage["Compute"] = 4] = "Compute"; -})(ShaderStage || (ShaderStage = {})); - -export let TextureUsage; - -(function (TextureUsage) { - TextureUsage[TextureUsage["CopySrc"] = 1] = "CopySrc"; - TextureUsage[TextureUsage["CopyDst"] = 2] = "CopyDst"; - TextureUsage[TextureUsage["Sampled"] = 4] = "Sampled"; - TextureUsage[TextureUsage["Storage"] = 8] = "Storage"; - TextureUsage[TextureUsage["OutputAttachment"] = 16] = "OutputAttachment"; -})(TextureUsage || (TextureUsage = {})); -//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/allowed_characters.js b/tests/wpt/web-platform-tests/webgpu/common/framework/allowed_characters.js deleted file mode 100644 index af8f45172b5..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/allowed_characters.js +++ /dev/null @@ -1,7 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -// It may be OK to add more allowed characters here. -export const allowedTestNameCharacters = 'a-zA-Z0-9/_'; -//# sourceMappingURL=allowed_characters.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/collect_garbage.js b/tests/wpt/web-platform-tests/webgpu/common/framework/collect_garbage.js deleted file mode 100644 index dc5a9caf850..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/collect_garbage.js +++ /dev/null @@ -1,48 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -export function attemptGarbageCollection() { - const w = self; - - if (w.GCController) { - w.GCController.collect(); - return; - } - - if (w.opera && w.opera.collect) { - w.opera.collect(); - return; - } - - try { - w.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils).garbageCollect(); - return; - } catch (e) {} - - if (w.gc) { - w.gc(); - return; - } - - if (w.CollectGarbage) { - w.CollectGarbage(); - return; - } - - let i; - - function gcRec(n) { - if (n < 1) return; - let temp = { - i: 'ab' + i + i / 100000 - }; - temp = temp + 'foo'; - gcRec(n - 1); - } - - for (i = 0; i < 1000; i++) { - gcRec(10); - } -} -//# sourceMappingURL=collect_garbage.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/file_loader.js b/tests/wpt/web-platform-tests/webgpu/common/framework/file_loader.js index 1b77a4e8595..0f25ca465d3 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/file_loader.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/file_loader.js @@ -14,10 +14,10 @@ export class TestFileLoader { } async loadTree(query, subqueriesToExpand = []) { - return loadTreeForQuery(this, parseQuery(query), subqueriesToExpand.map(q => parseQuery(q))); + return loadTreeForQuery(this, query, subqueriesToExpand.map(q => parseQuery(q))); } - async loadTests(query) { + async loadCases(query) { const tree = await this.loadTree(query); return tree.iterateLeaves(); } diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/generate_minimal_query_list.js b/tests/wpt/web-platform-tests/webgpu/common/framework/generate_minimal_query_list.js deleted file mode 100644 index f5344545725..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/generate_minimal_query_list.js +++ /dev/null @@ -1,106 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -import { Logger } from './logger.js'; -import { makeFilter } from './test_filter/load_filter.js'; -import { treeFromFilterResults } from './tree.js'; - -function makeQuerySplitterTree(caselist, expectationStrings) { - const expectations = []; - - for (const e of expectationStrings) { - const filter = makeFilter(e); - const id = filter.idIfSingle(); - - if (!id) { - throw new Error('Can only handle expectations which cover one file, one test, or one case. ' + e); - } - - expectations.push({ - id, - line: e, - seen: false - }); - } - - const convertToQuerySplitterTree = (tree, name) => { - const children = tree.children; - let needsSplit = true; - - if (name !== undefined) { - const filter = makeFilter(name); - const moreThanOneFile = !filter.definitelyOneFile(); - const matchingExpectations = expectations.map(e => { - const matches = filter.matches(e.id); - if (matches) e.seen = true; - return matches; - }); - needsSplit = matchingExpectations.some(m => m) || moreThanOneFile; - } - - const queryNode = { - needsSplit - }; - - if (children) { - queryNode.children = new Map(); - - for (const [k, v] of children) { - const subtree = convertToQuerySplitterTree(v, k); - queryNode.children.set(k, subtree); - } - } - - return queryNode; - }; - - const log = new Logger(); - const tree = treeFromFilterResults(log, caselist.values()); - const queryTree = convertToQuerySplitterTree(tree); - - for (const e of expectations) { - if (!e.seen) throw new Error('expectation had no effect: ' + e.line); - } - - return queryTree; -} // Takes a TestFilterResultIterator enumerating every test case in the suite, and a list of -// expectation queries from a browser's expectations file. Creates a minimal list of queries -// (i.e. wpt variant lines) such that: -// -// - There is at least one query per spec file. -// - Each of those those input queries is in the output, so that it can have its own expectation. -// -// It does this by creating a tree from the list of cases (same tree as the standalone runner uses), -// then marking every node which is a parent of a node that matches an expectation. - - -export async function generateMinimalQueryList(caselist, expectationStrings) { - const unsplitNodes = []; - - const findUnsplitNodes = (name, node) => { - if (node === undefined) { - return; - } - - if (node.needsSplit && node.children) { - for (const [k, v] of node.children) { - findUnsplitNodes(k, v); - } - } else { - unsplitNodes.push(name); - } - }; - - const queryTree = makeQuerySplitterTree(caselist, expectationStrings); - findUnsplitNodes('', queryTree); - - for (const exp of expectationStrings) { - if (!unsplitNodes.some(name => name === exp)) { - throw new Error('Something went wrong: all expectation strings should always appear exactly: ' + exp); - } - } - - return unsplitNodes; -} -//# sourceMappingURL=generate_minimal_query_list.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/id.js b/tests/wpt/web-platform-tests/webgpu/common/framework/id.js deleted file mode 100644 index cb21a667d60..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/id.js +++ /dev/null @@ -1,8 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -export function testSpecEquals(x, y) { - return x.suite === y.suite && x.path === y.path; -} // Identifies a test case (a specific parameterization of a test), within its spec file. -//# sourceMappingURL=id.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/listing.js b/tests/wpt/web-platform-tests/webgpu/common/framework/listing.js deleted file mode 100644 index 856afa99c36..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/listing.js +++ /dev/null @@ -1,4 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ -//# sourceMappingURL=listing.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/loader.js b/tests/wpt/web-platform-tests/webgpu/common/framework/loader.js deleted file mode 100644 index ac175a5b85f..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/loader.js +++ /dev/null @@ -1,50 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -import { loadFilter } from './test_filter/load_filter.js'; - -function* concat(lists) { - for (const specs of lists) { - yield* specs; - } -} - -class DefaultTestFileLoader { - async listing(suite) { - return (await import(`../../${suite}/listing.js`)).listing; - } - - import(path) { - return import('../../' + path); - } - -} - -export class TestLoader { - constructor(fileLoader = new DefaultTestFileLoader()) { - _defineProperty(this, "fileLoader", void 0); - - this.fileLoader = fileLoader; - } // TODO: Test - - - async loadTestsFromQuery(query) { - return this.loadTests(new URLSearchParams(query).getAll('q')); - } // TODO: Test - // TODO: Probably should actually not exist at all, just use queries on cmd line too. - - - async loadTestsFromCmdLine(filters) { - return this.loadTests(filters); - } - - async loadTests(filters) { - const loads = filters.map(f => loadFilter(this.fileLoader, f)); - return concat((await Promise.all(loads))); - } - -} -//# sourceMappingURL=loader.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/logger.js b/tests/wpt/web-platform-tests/webgpu/common/framework/logger.js deleted file mode 100644 index 3f624a86e32..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/logger.js +++ /dev/null @@ -1,155 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -import { SkipTestCase } from './fixture.js'; -import { extractPublicParams } from './params_utils.js'; -import { makeQueryString } from './url_query.js'; -import { getStackTrace } from './util/stack.js'; -import { assert, now } from './util/util.js'; -import { version } from './version.js'; -export class LogMessageWithStack extends Error { - constructor(name, ex, includeStack = true) { - super(ex.message); - this.name = name; - this.stack = includeStack ? ex.stack : undefined; - } - - toJSON() { - let m = this.name; - - if (this.message) { - m += ': ' + this.message; - } - - if (this.stack) { - m += '\n' + getStackTrace(this); - } - - return m; - } - -} -export class Logger { - constructor() { - _defineProperty(this, "results", []); - } - - record(spec) { - const result = { - spec: makeQueryString(spec), - cases: [] - }; - this.results.push(result); - return [new TestSpecRecorder(result), result]; - } - - asJSON(space) { - return JSON.stringify({ - version, - results: this.results - }, undefined, space); - } - -} -export class TestSpecRecorder { - constructor(result) { - _defineProperty(this, "result", void 0); - - this.result = result; - } - - record(test, params) { - const result = { - test, - params: params ? extractPublicParams(params) : null, - status: 'running', - timems: -1 - }; - this.result.cases.push(result); - return [new TestCaseRecorder(result), result]; - } - -} -var PassState; - -(function (PassState) { - PassState[PassState["pass"] = 0] = "pass"; - PassState[PassState["skip"] = 1] = "skip"; - PassState[PassState["warn"] = 2] = "warn"; - PassState[PassState["fail"] = 3] = "fail"; -})(PassState || (PassState = {})); - -export class TestCaseRecorder { - constructor(result) { - _defineProperty(this, "result", void 0); - - _defineProperty(this, "state", PassState.pass); - - _defineProperty(this, "startTime", -1); - - _defineProperty(this, "logs", []); - - _defineProperty(this, "debugging", false); - - this.result = result; - } - - start(debug = false) { - this.startTime = now(); - this.logs = []; - this.state = PassState.pass; - this.debugging = debug; - } - - finish() { - assert(this.startTime >= 0, 'finish() before start()'); - const endTime = now(); // Round to next microsecond to avoid storing useless .xxxx00000000000002 in results. - - this.result.timems = Math.ceil((endTime - this.startTime) * 1000) / 1000; - this.result.status = PassState[this.state]; - this.result.logs = this.logs; - this.debugging = false; - } - - debug(ex) { - if (!this.debugging) { - return; - } - - this.logs.push(new LogMessageWithStack('DEBUG', ex, false)); - } - - warn(ex) { - this.setState(PassState.warn); - this.logs.push(new LogMessageWithStack('WARN', ex)); - } - - fail(ex) { - this.setState(PassState.fail); - this.logs.push(new LogMessageWithStack('FAIL', ex)); - } - - skipped(ex) { - this.setState(PassState.skip); - this.logs.push(new LogMessageWithStack('SKIP', ex)); - } - - threw(ex) { - if (ex instanceof SkipTestCase) { - this.skipped(ex); - return; - } - - this.setState(PassState.fail); - this.logs.push(new LogMessageWithStack('EXCEPTION', ex)); - } - - setState(state) { - this.state = Math.max(this.state, state); - } - -} -//# sourceMappingURL=logger.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/params.js b/tests/wpt/web-platform-tests/webgpu/common/framework/params.js deleted file mode 100644 index f8e46b62dba..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/params.js +++ /dev/null @@ -1,135 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -let _Symbol$iterator, _Symbol$iterator2, _Symbol$iterator3, _Symbol$iterator4; - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -import { paramsEquals } from './params_utils.js'; -import { assert } from './util/util.js'; -export function poptions(name, values) { - return new POptions(name, values); -} -export function pbool(name) { - return new POptions(name, [false, true]); -} -export function pexclude(params, exclude) { - return new PExclude(params, exclude); -} -export function pfilter(cases, pred) { - return new PFilter(cases, pred); -} -export function pcombine(...params) { - return new PCombine(params); -} -_Symbol$iterator = Symbol.iterator; - -class POptions { - constructor(name, values) { - _defineProperty(this, "name", void 0); - - _defineProperty(this, "values", void 0); - - this.name = name; - this.values = values; - } - - *[_Symbol$iterator]() { - for (const value of this.values) { - yield { - [this.name]: value - }; - } - } - -} - -_Symbol$iterator2 = Symbol.iterator; - -class PExclude { - constructor(cases, exclude) { - _defineProperty(this, "cases", void 0); - - _defineProperty(this, "exclude", void 0); - - this.cases = cases; - this.exclude = Array.from(exclude); - } - - *[_Symbol$iterator2]() { - for (const p of this.cases) { - if (this.exclude.every(e => !paramsEquals(p, e))) { - yield p; - } - } - } - -} - -_Symbol$iterator3 = Symbol.iterator; - -class PFilter { - constructor(cases, pred) { - _defineProperty(this, "cases", void 0); - - _defineProperty(this, "pred", void 0); - - this.cases = cases; - this.pred = pred; - } - - *[_Symbol$iterator3]() { - for (const p of this.cases) { - if (this.pred(p)) { - yield p; - } - } - } - -} - -_Symbol$iterator4 = Symbol.iterator; - -class PCombine { - constructor(params) { - _defineProperty(this, "params", void 0); - - this.params = params; - } - - [_Symbol$iterator4]() { - return PCombine.cartesian(this.params); - } - - static merge(a, b) { - for (const key of Object.keys(a)) { - assert(!b.hasOwnProperty(key), 'Duplicate key: ' + key); - } - - return { ...a, - ...b - }; - } - - static *cartesian(iters) { - if (iters.length === 0) { - return; - } - - if (iters.length === 1) { - yield* iters[0]; - return; - } - - const [as, ...rest] = iters; - - for (const a of as) { - for (const b of PCombine.cartesian(rest)) { - yield PCombine.merge(a, b); - } - } - } - -} -//# sourceMappingURL=params.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/query/compare.js b/tests/wpt/web-platform-tests/webgpu/common/framework/query/compare.js index 2cbe6cc80c9..52396f352e6 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/query/compare.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/query/compare.js @@ -4,8 +4,12 @@ import { paramKeyIsPublic } from '../params_utils.js'; import { assert, objectEquals } from '../util/util.js'; -export let Ordering; // Compares two queries for their ordering (which is used to build the tree). -// See src/unittests/query_compare.spec.ts for examples. +export let Ordering; +/** + * Compares two queries for their ordering (which is used to build the tree). + * + * See src/unittests/query_compare.spec.ts for examples. + */ (function (Ordering) { Ordering[Ordering["Unordered"] = 0] = "Unordered"; @@ -40,10 +44,14 @@ export function compareQueries(a, b) { } return Ordering.Equal; -} // Compares a single level of a query. -// "IsBig" means the query is big relative to the level, e.g. for test-level: -// anything >= suite:a,* is big -// anything <= suite:a:* is small +} +/** + * Compares a single level of a query. + * + * "IsBig" means the query is big relative to the level, e.g. for test-level: + * - Anything >= `suite:a,*` is big + * - Anything <= `suite:a:*` is small + */ function compareOneLevel(ordering, aIsBig, bIsBig) { assert(ordering !== Ordering.Equal || aIsBig || bIsBig); diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/query/encode_selectively.js b/tests/wpt/web-platform-tests/webgpu/common/framework/query/encode_selectively.js index d67f1042233..e153cf8ccd8 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/query/encode_selectively.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/query/encode_selectively.js @@ -2,11 +2,15 @@ * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts **/ -// Encodes a stringified TestQuery so that it can be placed in a `?q=` parameter in a URL. -// encodeURIComponent encodes in accordance with `application/x-www-form-urlencoded`, but URLs don't -// actually have to be as strict as HTML form encoding (we interpret this purely from JavaScript). -// So we encode the component, then selectively convert some %-encoded escape codes back to their -// original form for readability/copyability. +/** + * Encodes a stringified TestQuery so that it can be placed in a `?q=` parameter in a URL. + * + * `encodeURIComponent` encodes in accordance with `application/x-www-form-urlencoded`, + * but URLs don't actually have to be as strict as HTML form encoding + * (we interpret this purely from JavaScript). + * So we encode the component, then selectively convert some %-encoded escape codes + * back to their original form for readability/copyability. + */ export function encodeURIComponentSelectively(s) { let ret = encodeURIComponent(s); ret = ret.replace(/%22/g, '"'); // for JSON strings diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/query/query.js b/tests/wpt/web-platform-tests/webgpu/common/framework/query/query.js index b80b6904f17..8b352241f8b 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/query/query.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/query/query.js @@ -8,8 +8,23 @@ import { assert } from '../util/util.js'; import { encodeURIComponentSelectively } from './encode_selectively.js'; import { kBigSeparator, kPathSeparator, kWildcard, kParamSeparator } from './separators.js'; import { stringifyPublicParams } from './stringify_params.js'; +/** + * Represents a test query of some level. + * + * TestQuery types are immutable. + */ + +// SingleCase + +/** + * A multi-file test query, like `s:*` or `s:a,b,*`. + * + * Immutable (makes copies of constructor args). + */ export class TestQueryMultiFile { constructor(suite, file) { + _defineProperty(this, "level", 1); + _defineProperty(this, "isMultiFile", true); _defineProperty(this, "suite", void 0); @@ -24,19 +39,23 @@ export class TestQueryMultiFile { return encodeURIComponentSelectively(this.toStringHelper().join(kBigSeparator)); } - toHTML() { - return this.toStringHelper().join(kBigSeparator + ''); - } - toStringHelper() { return [this.suite, [...this.filePathParts, kWildcard].join(kPathSeparator)]; } } +/** + * A multi-test test query, like `s:f:*` or `s:f:a,b,*`. + * + * Immutable (makes copies of constructor args). + */ + export class TestQueryMultiTest extends TestQueryMultiFile { constructor(suite, file, test) { super(suite, file); + _defineProperty(this, "level", 2); + _defineProperty(this, "isMultiFile", false); _defineProperty(this, "isMultiTest", true); @@ -52,10 +71,19 @@ export class TestQueryMultiTest extends TestQueryMultiFile { } } +/** + * A multi-case test query, like `s:f:t:*` or `s:f:t:a,b,*`. + * + * Immutable (makes copies of constructor args), except for param values + * (which aren't normally supposed to change; they're marked readonly in CaseParams). + */ + export class TestQueryMultiCase extends TestQueryMultiTest { constructor(suite, file, test, params) { super(suite, file, test); + _defineProperty(this, "level", 3); + _defineProperty(this, "isMultiTest", false); _defineProperty(this, "isMultiCase", true); @@ -73,10 +101,18 @@ export class TestQueryMultiCase extends TestQueryMultiTest { } } +/** + * A multi-case test query, like `s:f:t:` or `s:f:t:a=1,b=1`. + * + * Immutable (makes copies of constructor args). + */ + export class TestQuerySingleCase extends TestQueryMultiCase { constructor(...args) { super(...args); + _defineProperty(this, "level", 4); + _defineProperty(this, "isMultiCase", false); } diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/query/separators.js b/tests/wpt/web-platform-tests/webgpu/common/framework/query/separators.js index 4782fe457b8..e378a9d1d29 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/query/separators.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/query/separators.js @@ -2,13 +2,18 @@ * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts **/ -export const kBigSeparator = ':'; // Separator between big parts: suite:file:test:case +/** Separator between big parts: suite:file:test:case */ +export const kBigSeparator = ':'; +/** Separator between path,to,file or path,to,test */ -export const kPathSeparator = ','; // Separator between path,to,file or path,to,test +export const kPathSeparator = ','; +/** Separator between k=v;k=v */ -export const kParamSeparator = ';'; // Separator between k=v;k=v +export const kParamSeparator = ';'; +/** Separator between key and value in k=v */ -export const kParamKVSeparator = '='; // Separator between key and value in k=v +export const kParamKVSeparator = '='; +/** Final wildcard, if query is not single-case */ -export const kWildcard = '*'; // Final wildcard, if query is not single-case +export const kWildcard = '*'; //# sourceMappingURL=separators.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/query/validQueryPart.js b/tests/wpt/web-platform-tests/webgpu/common/framework/query/validQueryPart.js index f51ebade76a..3c051afc94b 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/query/validQueryPart.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/query/validQueryPart.js @@ -2,6 +2,6 @@ * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts **/ -// Applies to group parts, test parts, params keys. +/** Applies to group parts, test parts, params keys. */ export const validQueryPart = /^[a-zA-Z0-9_]+$/; //# sourceMappingURL=validQueryPart.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_by_group.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_by_group.js deleted file mode 100644 index b43749f9c5d..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_by_group.js +++ /dev/null @@ -1,64 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -export class FilterByGroup { - constructor(suite, groupPrefix) { - _defineProperty(this, "suite", void 0); - - _defineProperty(this, "specPathPrefix", void 0); - - this.suite = suite; - this.specPathPrefix = groupPrefix; - } - - matches(id) { - return id.spec.suite === this.suite && this.pathMatches(id.spec.path); - } - - async iterate(loader) { - const specs = await loader.listing(this.suite); - const entries = []; - const suite = this.suite; - - for (const { - path, - description - } of specs) { - if (this.pathMatches(path)) { - const isReadme = path === '' || path.endsWith('/'); - const spec = isReadme ? { - description - } : await loader.import(`${suite}/${path}.spec.js`); - entries.push({ - id: { - suite, - path - }, - spec - }); - } - } - - return entries; - } - - definitelyOneFile() { - // FilterByGroup could always possibly match multiple files, because it represents a prefix, - // e.g. "a:b" not "a:b:". - return false; - } - - idIfSingle() { - // FilterByGroup could be one whole suite, but we only want whole files, tests, or cases. - return undefined; - } - - pathMatches(path) { - return path.startsWith(this.specPathPrefix); - } - -} -//# sourceMappingURL=filter_by_group.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_one_file.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_one_file.js deleted file mode 100644 index cc261ad2ac1..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/filter_one_file.js +++ /dev/null @@ -1,167 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -import { testSpecEquals } from '../id.js'; -import { paramsEquals, paramsSupersets } from '../params_utils.js'; - -class FilterOneFile { - constructor(specId) { - _defineProperty(this, "specId", void 0); - - this.specId = specId; - } - - async iterate(loader) { - const spec = await loader.import(`${this.specId.suite}/${this.specId.path}.spec.js`); - return [{ - id: this.specId, - spec: { - description: spec.description, - g: this.getCases(spec) - } - }]; - } - - definitelyOneFile() { - return true; - } - -} - -function filterTestGroup(group, filter) { - return { - *iterate(log) { - for (const rc of group.iterate(log)) { - if (filter(rc.id)) { - yield rc; - } - } - } - - }; -} - -export class FilterByTestMatch extends FilterOneFile { - constructor(specId, testPrefix) { - super(specId); - - _defineProperty(this, "testPrefix", void 0); - - this.testPrefix = testPrefix; - } - - getCases(spec) { - return filterTestGroup(spec.g, testcase => this.testMatches(testcase.test)); - } - - idIfSingle() { - if (this.testPrefix.length !== 0) { - return undefined; - } // This is one whole spec file. - - - return { - spec: this.specId - }; - } - - matches(id) { - if (id.test === undefined) { - return false; - } - - return testSpecEquals(id.spec, this.specId) && this.testMatches(id.test); - } - - testMatches(test) { - return test.startsWith(this.testPrefix); - } - -} -export class FilterByParamsMatch extends FilterOneFile { - constructor(specId, test, params) { - super(specId); - - _defineProperty(this, "test", void 0); - - _defineProperty(this, "params", void 0); - - this.test = test; - this.params = params; - } - - getCases(spec) { - return filterTestGroup(spec.g, testcase => this.caseMatches(testcase.test, testcase.params)); - } - - idIfSingle() { - if (this.params !== null) { - return undefined; - } // This is one whole test. - - - return { - spec: this.specId, - test: this.test - }; - } - - matches(id) { - if (id.test === undefined) { - return false; - } - - return testSpecEquals(id.spec, this.specId) && this.caseMatches(id.test, id.params); - } - - caseMatches(test, params) { - if (params === undefined) { - return false; - } - - return test === this.test && paramsSupersets(params, this.params); - } - -} -export class FilterByParamsExact extends FilterOneFile { - constructor(specId, test, params) { - super(specId); - - _defineProperty(this, "test", void 0); - - _defineProperty(this, "params", void 0); - - this.test = test; - this.params = params; - } - - getCases(spec) { - return filterTestGroup(spec.g, testcase => this.caseMatches(testcase.test, testcase.params)); - } - - idIfSingle() { - // This is one single test case. - return { - spec: this.specId, - test: this.test, - params: this.params - }; - } - - matches(id) { - if (id.test === undefined || id.params === undefined) { - return false; - } - - return testSpecEquals(id.spec, this.specId) && this.caseMatches(id.test, id.params); - } - - caseMatches(test, params) { - return test === this.test && paramsEquals(params, this.params); - } - -} -//# sourceMappingURL=filter_one_file.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/internal.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/internal.js deleted file mode 100644 index ae55718f3b3..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/internal.js +++ /dev/null @@ -1,4 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ -//# sourceMappingURL=internal.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/load_filter.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/load_filter.js deleted file mode 100644 index 2b13d9ed2c9..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/load_filter.js +++ /dev/null @@ -1,71 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -import { allowedTestNameCharacters } from '../allowed_characters.js'; -import { assert, unreachable } from '../util/util.js'; -import { FilterByGroup } from './filter_by_group.js'; -import { FilterByParamsExact, FilterByParamsMatch, FilterByTestMatch } from './filter_one_file.js'; -// Each filter is of one of the forms below (urlencoded). -export function makeFilter(filter) { - const i1 = filter.indexOf(':'); - assert(i1 !== -1, 'Test queries must fully specify their suite name (e.g. "webgpu:")'); - const suite = filter.substring(0, i1); - const i2 = filter.indexOf(':', i1 + 1); - - if (i2 === -1) { - // - webgpu: - // - webgpu:buf - // - webgpu:buffers/ - // - webgpu:buffers/map - const groupPrefix = filter.substring(i1 + 1); - return new FilterByGroup(suite, groupPrefix); - } - - const path = filter.substring(i1 + 1, i2); - const endOfTestName = new RegExp('[^' + allowedTestNameCharacters + ']'); - const i3sub = filter.substring(i2 + 1).search(endOfTestName); - - if (i3sub === -1) { - // - webgpu:buffers/mapWriteAsync: - // - webgpu:buffers/mapWriteAsync:b - const testPrefix = filter.substring(i2 + 1); - return new FilterByTestMatch({ - suite, - path - }, testPrefix); - } - - const i3 = i2 + 1 + i3sub; - const test = filter.substring(i2 + 1, i3); - const token = filter.charAt(i3); - let params = null; - - if (i3 + 1 < filter.length) { - params = JSON.parse(filter.substring(i3 + 1)); - } - - if (token === '~') { - // - webgpu:buffers/mapWriteAsync:basic~ - // - webgpu:buffers/mapWriteAsync:basic~{} - // - webgpu:buffers/mapWriteAsync:basic~{filter:"params"} - return new FilterByParamsMatch({ - suite, - path - }, test, params); - } else if (token === '=') { - // - webgpu:buffers/mapWriteAsync:basic= - // - webgpu:buffers/mapWriteAsync:basic={} - // - webgpu:buffers/mapWriteAsync:basic={exact:"params"} - return new FilterByParamsExact({ - suite, - path - }, test, params); - } else { - unreachable("invalid character after test name; must be '~' or '='"); - } -} -export function loadFilter(loader, filter) { - return makeFilter(filter).iterate(loader); -} -//# sourceMappingURL=load_filter.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/test_filter_result.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/test_filter_result.js deleted file mode 100644 index 9e32bdbd931..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_filter/test_filter_result.js +++ /dev/null @@ -1,4 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ -//# sourceMappingURL=test_filter_result.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/test_group.js b/tests/wpt/web-platform-tests/webgpu/common/framework/test_group.js index ef34b5fd51c..5ced9cd3d37 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/test_group.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/test_group.js @@ -105,7 +105,7 @@ class TestBuilder { } *iterate() { - assert(this.testFn !== undefined, 'internal error'); + assert(this.testFn !== undefined, 'No test function (.fn()) for test'); for (const params of this.cases || [{}]) { yield new RunCaseSpecific(this.testPath, params, this.fixture, this.testFn); diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/tree.js b/tests/wpt/web-platform-tests/webgpu/common/framework/tree.js index 2f4329c164d..69dfac21a63 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/tree.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/tree.js @@ -6,6 +6,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope import { compareQueries, Ordering } from './query/compare.js'; import { TestQueryMultiCase, TestQuerySingleCase, TestQueryMultiFile, TestQueryMultiTest } from './query/query.js'; +import { kBigSeparator, kWildcard, kPathSeparator, kParamSeparator } from './query/separators.js'; import { stringifySingleParam } from './query/stringify_params.js'; import { assert } from './util/util.js'; // `loadTreeForQuery()` loads a TestTree for a given queryToLoad. // The resulting tree is a linked-list all the way from `suite:*` to queryToLoad, @@ -45,6 +46,20 @@ export class TestTree { iterateLeaves() { return TestTree.iterateSubtreeLeaves(this.root); } + /** + * If a parent and its child are at different levels, then + * generally the parent has only one child, i.e.: + * a,* { a,b,* { a,b:* { ... } } } + * Collapse that down into: + * a,* { a,b:* { ... } } + * which is less needlessly verbose when displaying the tree in the standalone runner. + */ + + + dissolveLevelBoundaries() { + const newRoot = dissolveLevelBoundaries(this.root); + assert(newRoot === this.root); + } toString() { return TestTree.subtreeToString('(root)', this.root, ''); @@ -72,11 +87,11 @@ export class TestTree { static subtreeToString(name, tree, indent) { const collapsible = 'run' in tree ? '>' : tree.collapsible ? '+' : '-'; - let s = indent + `${collapsible} ${JSON.stringify(name)} => ` + `${tree.query} ${JSON.stringify(tree.query)}`; + let s = indent + `${collapsible} ${JSON.stringify(name)} => ${tree.query}`; if ('children' in tree) { if (tree.description !== undefined) { - s += indent + `\n | ${JSON.stringify(tree.description)}`; + s += `\n${indent} | ${JSON.stringify(tree.description)}`; } for (const [name, child] of tree.children) { @@ -167,21 +182,19 @@ export async function loadTreeForQuery(loader, queryToLoad, subqueriesToExpand) } } - const tree = new TestTree(subtreeL0); - for (const [i, sq] of subqueriesToExpandEntries) { const seen = seenSubqueriesToExpand[i]; assert(seen, `subqueriesToExpand entry did not match anything \ (can happen due to overlap with another subquery): ${sq.toString()}`); } - assert(foundCase, 'Query does not match any cases'); // TODO: Contains lots of single-child subtrees. Consider cleaning those up (as postprocess?). - - return tree; + assert(foundCase, 'Query does not match any cases'); + return new TestTree(subtreeL0); } function makeTreeForSuite(suite) { return { + readableRelativeName: suite + kBigSeparator, query: new TestQueryMultiFile(suite, []), children: new Map(), collapsible: false @@ -197,6 +210,7 @@ function addSubtreeForDirPath(tree, file) { tree = getOrInsertSubtree(part, tree, () => { const query = new TestQueryMultiFile(tree.query.suite, subqueryFile); return { + readableRelativeName: part + kPathSeparator + kWildcard, query, collapsible: false }; @@ -213,7 +227,9 @@ function addSubtreeForFilePath(tree, file, description, checkCollapsible) { const subtree = getOrInsertSubtree('', tree, () => { const query = new TestQueryMultiTest(tree.query.suite, tree.query.filePathParts, []); + assert(file.length > 0, 'file path is empty'); return { + readableRelativeName: file[file.length - 1] + kBigSeparator + kWildcard, query, description, collapsible: checkCollapsible(query) @@ -231,6 +247,7 @@ function addSubtreeForTestPath(tree, test, isCollapsible) { tree = getOrInsertSubtree(part, tree, () => { const query = new TestQueryMultiTest(tree.query.suite, tree.query.filePathParts, subqueryTest); return { + readableRelativeName: part + kPathSeparator + kWildcard, query, collapsible: isCollapsible(query) }; @@ -240,7 +257,10 @@ function addSubtreeForTestPath(tree, test, isCollapsible) { return getOrInsertSubtree('', tree, () => { const query = new TestQueryMultiCase(tree.query.suite, tree.query.filePathParts, subqueryTest, {}); + assert(subqueryTest.length > 0, 'subqueryTest is empty'); return { + readableRelativeName: subqueryTest[subqueryTest.length - 1] + kBigSeparator + kWildcard, + kWildcard, query, collapsible: isCollapsible(query) }; @@ -259,6 +279,7 @@ function addLeafForCase(tree, t, checkCollapsible) { tree = getOrInsertSubtree(name, tree, () => { const subquery = new TestQueryMultiCase(query.suite, query.filePathParts, query.testPathParts, subqueryParams); return { + readableRelativeName: name + kParamSeparator + kWildcard, query: subquery, collapsible: checkCollapsible(subquery) }; @@ -293,10 +314,48 @@ function getOrInsertSubtree(key, parent, createSubtree) { function insertLeaf(parent, query, t) { const key = ''; const leaf = { + readableRelativeName: readableNameForCase(query), query, run: rec => t.run(rec) }; assert(!parent.children.has(key)); parent.children.set(key, leaf); } + +function dissolveLevelBoundaries(tree) { + if ('children' in tree) { + if (tree.children.size === 1 && tree.description === undefined) { + // Loops exactly once + for (const [, child] of tree.children) { + if (child.query.level > tree.query.level) { + const newtree = dissolveLevelBoundaries(child); + return newtree; + } + } + } + + for (const [k, child] of tree.children) { + const newChild = dissolveLevelBoundaries(child); + + if (newChild !== child) { + tree.children.set(k, newChild); + } + } + } + + return tree; +} +/** Generate a readable relative name for a case (used in standalone). */ + + +function readableNameForCase(query) { + const paramsKeys = Object.keys(query.params); + + if (paramsKeys.length === 0) { + return query.testPathParts[query.testPathParts.length - 1] + kBigSeparator; + } else { + const lastKey = paramsKeys[paramsKeys.length - 1]; + return stringifySingleParam(lastKey, query.params[lastKey]); + } +} //# sourceMappingURL=tree.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/url_query.js b/tests/wpt/web-platform-tests/webgpu/common/framework/url_query.js deleted file mode 100644 index 13671ab7dac..00000000000 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/url_query.js +++ /dev/null @@ -1,48 +0,0 @@ -/** -* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts -**/ - -import { stringifyPublicParams } from './params_utils.js'; -import { unreachable } from './util/util.js'; -export function encodeSelectively(s) { - let ret = encodeURIComponent(s); - ret = ret.replace(/%22/g, '"'); - ret = ret.replace(/%2C/g, ','); - ret = ret.replace(/%2F/g, '/'); - ret = ret.replace(/%3A/g, ':'); - ret = ret.replace(/%3D/g, '='); - ret = ret.replace(/%5B/g, '['); - ret = ret.replace(/%5D/g, ']'); - ret = ret.replace(/%7B/g, '{'); - ret = ret.replace(/%7D/g, '}'); - return ret; -} -export function checkPublicParamType(v) { - if (typeof v === 'number' || typeof v === 'string' || typeof v === 'boolean' || v === undefined) { - return; - } - - if (v instanceof Array) { - for (const x of v) { - if (typeof x !== 'number') { - break; - } - } - - return; - } - - unreachable('Invalid type for test case params ' + v); -} -export function makeQueryString(spec, testcase) { - let s = spec.suite + ':'; - s += spec.path + ':'; - - if (testcase !== undefined) { - s += testcase.test + '='; - s += stringifyPublicParams(testcase.params); - } - - return encodeSelectively(s); -} -//# sourceMappingURL=url_query.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/util/collect_garbage.js b/tests/wpt/web-platform-tests/webgpu/common/framework/util/collect_garbage.js index 83b797a0cc4..d4b5bb19b23 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/util/collect_garbage.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/util/collect_garbage.js @@ -39,6 +39,8 @@ export async function attemptGarbageCollection() { i: 'ab' + i + i / 100000 }; temp = temp + 'foo'; + temp; // dummy use of unused variable + gcRec(n - 1); } diff --git a/tests/wpt/web-platform-tests/webgpu/common/framework/version.js b/tests/wpt/web-platform-tests/webgpu/common/framework/version.js index f1fe61edc7f..4b233137825 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/framework/version.js +++ b/tests/wpt/web-platform-tests/webgpu/common/framework/version.js @@ -1,3 +1,3 @@ // AUTO-GENERATED - DO NOT EDIT. See tools/gen_version. -export const version = 'd8d0ca524c80a0086ab70e155b80589a6be2b6f6'; +export const version = '21f8f997c1db17e2daa6d0c9e8794a5c3216f373'; diff --git a/tests/wpt/web-platform-tests/webgpu/common/runtime/helper/test_worker-worker.js b/tests/wpt/web-platform-tests/webgpu/common/runtime/helper/test_worker-worker.js index be3f4952f05..a02c98c2bbf 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/runtime/helper/test_worker-worker.js +++ b/tests/wpt/web-platform-tests/webgpu/common/runtime/helper/test_worker-worker.js @@ -4,6 +4,7 @@ import { DefaultTestFileLoader } from '../../framework/file_loader.js'; import { Logger } from '../../framework/logging/logger.js'; +import { parseQuery } from '../../framework/query/parseQuery.js'; import { assert } from '../../framework/util/util.js'; // should be DedicatedWorkerGlobalScope const loader = new DefaultTestFileLoader(); @@ -12,7 +13,7 @@ self.onmessage = async ev => { const query = ev.data.query; const debug = ev.data.debug; const log = new Logger(debug); - const testcases = Array.from((await loader.loadTests(query))); + const testcases = Array.from(await loader.loadCases(parseQuery(query))); assert(testcases.length === 1, 'worker query resulted in != 1 cases'); const testcase = testcases[0]; const [rec, result] = log.record(testcase.query.toString()); diff --git a/tests/wpt/web-platform-tests/webgpu/common/runtime/wpt.js b/tests/wpt/web-platform-tests/webgpu/common/runtime/wpt.js index 0648a0dc7ee..dc38b77b1d5 100644 --- a/tests/wpt/web-platform-tests/webgpu/common/runtime/wpt.js +++ b/tests/wpt/web-platform-tests/webgpu/common/runtime/wpt.js @@ -4,6 +4,7 @@ import { DefaultTestFileLoader } from '../framework/file_loader.js'; import { Logger } from '../framework/logging/logger.js'; +import { parseQuery } from '../framework/query/parseQuery.js'; import { AsyncMutex } from '../framework/util/async_mutex.js'; import { assert } from '../framework/util/util.js'; import { optionEnabled } from './helper/options.js'; @@ -13,9 +14,9 @@ import { TestWorker } from './helper/test_worker.js'; const loader = new DefaultTestFileLoader(); const qs = new URLSearchParams(window.location.search).getAll('q'); assert(qs.length === 1, 'currently, there must be exactly one ?q='); - const testcases = await loader.loadTests(qs[0]); + const testcases = await loader.loadCases(parseQuery(qs[0])); await addWPTTests(testcases); -})(); // Note: async_tests must ALL be added within the same task. This function *must not* be async. +})(); // Note: `async_test`s must ALL be added within the same task. This function *must not* be async. function addWPTTests(testcases) { diff --git a/tests/wpt/web-platform-tests/webgpu/cts.html b/tests/wpt/web-platform-tests/webgpu/cts.html index a06ad795899..e78afee421a 100644 --- a/tests/wpt/web-platform-tests/webgpu/cts.html +++ b/tests/wpt/web-platform-tests/webgpu/cts.html @@ -51,5 +51,6 @@ + diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map.spec.js index 842421dd5ce..e8c86ec1b8a 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map.spec.js @@ -34,7 +34,7 @@ g.test('mapReadAsync').params(poptions('size', [12, 512 * 1024])).fn(async t => } buffer.unmap(); - const actual = new Uint8Array((await buffer.mapReadAsync())); + const actual = new Uint8Array(await buffer.mapReadAsync()); t.expectBuffer(actual, new Uint8Array(expected.buffer)); }); g.test('createBufferMapped').params(params().combine(poptions('size', [12, 512 * 1024])).combine(pbool('mappable'))).fn(async t => { diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map_oom.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map_oom.spec.js index a04347ffd4f..8494dc7ddc7 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map_oom.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/buffers/map_oom.spec.js @@ -6,25 +6,29 @@ export const description = ''; import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { GPUTest } from '../../../gpu_test.js'; -function getBufferDesc() { +function getBufferDesc(usage) { return { size: Number.MAX_SAFE_INTEGER, - usage: GPUBufferUsage.MAP_WRITE + usage }; } export const g = makeTestGroup(GPUTest); g.test('mapWriteAsync').fn(async t => { - const buffer = t.device.createBuffer(getBufferDesc()); - t.shouldReject('RangeError', buffer.mapWriteAsync()); + const buffer = t.expectGPUError('out-of-memory', () => { + return t.device.createBuffer(getBufferDesc(GPUBufferUsage.MAP_WRITE)); + }); + t.shouldReject('OperationError', buffer.mapWriteAsync()); }); g.test('mapReadAsync').fn(async t => { - const buffer = t.device.createBuffer(getBufferDesc()); - t.shouldReject('RangeError', buffer.mapReadAsync()); + const buffer = t.expectGPUError('out-of-memory', () => { + return t.device.createBuffer(getBufferDesc(GPUBufferUsage.MAP_READ)); + }); + t.shouldReject('OperationError', buffer.mapReadAsync()); }); g.test('createBufferMapped').fn(async t => { t.shouldThrow('RangeError', () => { - t.device.createBufferMapped(getBufferDesc()); + t.device.createBufferMapped(getBufferDesc(GPUBufferUsage.COPY_SRC)); }); }); //# sourceMappingURL=map_oom.spec.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/copied_texture_clear.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/copied_texture_clear.spec.js index 22a71bf725c..f5b8b697d74 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/copied_texture_clear.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/copied_texture_clear.spec.js @@ -3,7 +3,6 @@ **/ export const description = 'Test uninitialized textures are initialized to zero when copied.'; -import * as C from '../../../../common/constants.js'; import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { assert, unreachable } from '../../../../common/framework/util/util.js'; import { ReadMethod, TextureZeroInitTest } from './texture_zero_init_test.js'; @@ -38,7 +37,7 @@ class CopiedTextureClearTest extends TextureZeroInitTest { const dst = this.device.createTexture({ size: [width, height, 1], format: this.params.format, - usage: C.TextureUsage.CopyDst | C.TextureUsage.CopySrc + usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC }); const commandEncoder = this.device.createCommandEncoder(); commandEncoder.copyTextureToTexture({ diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/texture_zero_init_test.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/texture_zero_init_test.js index 5dc3c227232..8dda949f859 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/texture_zero_init_test.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/operation/resource_init/texture_zero_init_test.js @@ -4,7 +4,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } -import * as C from '../../../../common/constants.js'; import { params, poptions, pbool } from '../../../../common/framework/params_builder.js'; import { assert, unreachable } from '../../../../common/framework/util/util.js'; import { kTextureAspects, kTextureFormatInfo, kTextureFormats } from '../../../capability_info.js'; @@ -167,14 +166,14 @@ export function initializedStateAsStencil(state) { } function getRequiredTextureUsage(format, sampleCount, uninitializeMethod, readMethod) { - let usage = C.TextureUsage.CopyDst; + let usage = GPUTextureUsage.COPY_DST; switch (uninitializeMethod) { case UninitializeMethod.Creation: break; case UninitializeMethod.StoreOpClear: - usage |= C.TextureUsage.OutputAttachment; + usage |= GPUTextureUsage.OUTPUT_ATTACHMENT; break; default: @@ -184,21 +183,21 @@ function getRequiredTextureUsage(format, sampleCount, uninitializeMethod, readMe switch (readMethod) { case ReadMethod.CopyToBuffer: case ReadMethod.CopyToTexture: - usage |= C.TextureUsage.CopySrc; + usage |= GPUTextureUsage.COPY_SRC; break; case ReadMethod.Sample: - usage |= C.TextureUsage.Sampled; + usage |= GPUTextureUsage.SAMPLED; break; case ReadMethod.Storage: - usage |= C.TextureUsage.Storage; + usage |= GPUTextureUsage.STORAGE; break; case ReadMethod.DepthTest: case ReadMethod.StencilTest: case ReadMethod.ColorBlending: - usage |= C.TextureUsage.OutputAttachment; + usage |= GPUTextureUsage.OUTPUT_ATTACHMENT; break; default: @@ -208,14 +207,14 @@ function getRequiredTextureUsage(format, sampleCount, uninitializeMethod, readMe if (sampleCount > 1) { // Copies to multisampled textures are not allowed. We need OutputAttachment to initialize // canary data in multisampled textures. - usage |= C.TextureUsage.OutputAttachment; + usage |= GPUTextureUsage.OUTPUT_ATTACHMENT; } if (!kTextureFormatInfo[format].copyable) { // Copies are not possible. We need OutputAttachment to initialize // canary data. assert(kTextureFormatInfo[format].renderable); - usage |= C.TextureUsage.OutputAttachment; + usage |= GPUTextureUsage.OUTPUT_ATTACHMENT; } return usage; @@ -490,11 +489,11 @@ export class TextureZeroInitTest extends GPUTest { }) => { const usage = getRequiredTextureUsage(format, sampleCount, uninitializeMethod, readMethod); - if (usage & C.TextureUsage.OutputAttachment && !kTextureFormatInfo[format].renderable) { + if (usage & GPUTextureUsage.OUTPUT_ATTACHMENT && !kTextureFormatInfo[format].renderable) { return false; } - if (usage & C.TextureUsage.Storage && !kTextureFormatInfo[format].storage) { + if (usage & GPUTextureUsage.STORAGE && !kTextureFormatInfo[format].storage) { return false; } diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroup.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroup.spec.js index 1eb8f959f33..5deed893d5e 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroup.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroup.spec.js @@ -5,7 +5,6 @@ export const description = ` createBindGroup validation tests. `; -import * as C from '../../../common/constants.js'; import { poptions, params } from '../../../common/framework/params_builder.js'; import { makeTestGroup } from '../../../common/framework/test_group.js'; import { unreachable } from '../../../common/framework/util/util.js'; @@ -137,7 +136,7 @@ g.test('texture_binding_must_have_correct_usage').params(params().combine(poptio height: 16, depth: 1 }, - format: C.TextureFormat.RGBA8Unorm, + format: 'rgba8unorm', usage }; const shouldError = usage !== info.usage; @@ -151,7 +150,7 @@ g.test('texture_binding_must_have_correct_usage').params(params().combine(poptio }); }, shouldError); }); -g.test('texture_must_have_correct_component_type').params(poptions('textureComponentType', [C.TextureComponentType.Float, C.TextureComponentType.Sint, C.TextureComponentType.Uint])).fn(async t => { +g.test('texture_must_have_correct_component_type').params(poptions('textureComponentType', ['float', 'sint', 'uint'])).fn(async t => { const { textureComponentType } = t.params; @@ -239,7 +238,7 @@ g.test('texture_must_have_correct_dimension').fn(async t => { height: 16, depth: 1 }, - format: C.TextureFormat.RGBA8Unorm, + format: 'rgba8unorm', usage: GPUTextureUsage.SAMPLED }; // Control case diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroupLayout.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroupLayout.spec.js index 3961ba3a81a..2fec032c178 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroupLayout.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createBindGroupLayout.spec.js @@ -5,7 +5,6 @@ export const description = ` createBindGroupLayout validation tests. `; -import * as C from '../../../common/constants.js'; import { poptions, params } from '../../../common/framework/params_builder.js'; import { makeTestGroup } from '../../../common/framework/test_group.js'; import { kBindingTypeInfo, kBindingTypes, kMaxBindingsPerBindGroup, kShaderStages } from '../../capability_info.js'; @@ -21,11 +20,11 @@ g.test('some_binding_index_was_specified_more_than_once').fn(async t => { entries: [{ binding: 0, visibility: GPUShaderStage.COMPUTE, - type: C.BindingType.StorageBuffer + type: 'storage-buffer' }, { binding: 1, visibility: GPUShaderStage.COMPUTE, - type: C.BindingType.StorageBuffer + type: 'storage-buffer' }] }; // Control case @@ -47,10 +46,10 @@ g.test('visibility_of_bindings_can_be_0').fn(async t => { }); }); g.test('number_of_dynamic_buffers_exceeds_the_maximum_value').params([{ - type: C.BindingType.StorageBuffer, + type: 'storage-buffer', maxDynamicBufferCount: 4 }, { - type: C.BindingType.UniformBuffer, + type: 'uniform-buffer', maxDynamicBufferCount: 8 }]).fn(async t => { const { diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createPipelineLayout.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createPipelineLayout.spec.js index 262581e8714..4e293fa725d 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createPipelineLayout.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createPipelineLayout.spec.js @@ -5,7 +5,6 @@ export const description = ` createPipelineLayout validation tests. `; -import * as C from '../../../common/constants.js'; import { pbool, poptions, params } from '../../../common/framework/params_builder.js'; import { makeTestGroup } from '../../../common/framework/test_group.js'; import { kBindingTypeInfo, kBindingTypes, kShaderStageCombinations } from '../../capability_info.js'; @@ -16,7 +15,7 @@ function clone(descriptor) { } export const g = makeTestGroup(ValidationTest); -g.test('number_of_dynamic_buffers_exceeds_the_maximum_value').params(params().combine(poptions('visibility', [0, 2, 4, 6])).combine(poptions('type', [C.BindingType.UniformBuffer, C.BindingType.StorageBuffer, C.BindingType.ReadonlyStorageBuffer]))).fn(async t => { +g.test('number_of_dynamic_buffers_exceeds_the_maximum_value').params(params().combine(poptions('visibility', [0, 2, 4, 6])).combine(poptions('type', ['uniform-buffer', 'storage-buffer', 'readonly-storage-buffer']))).fn(async t => { const { type, visibility diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createView.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createView.spec.js index 524d921adaa..3ad1ca97d7d 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createView.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/api/validation/createView.spec.js @@ -5,7 +5,6 @@ export const description = ` createView validation tests. `; -import * as C from '../../../common/constants.js'; import { makeTestGroup } from '../../../common/framework/test_group.js'; import { ValidationTest } from './validation_test.js'; const ARRAY_LAYER_COUNT_2D = 6; @@ -69,7 +68,7 @@ g.test('creating_texture_view_on_a_2D_non_array_texture').params([{ _success: false }, // it is an error to view a layer past the end of the texture { - dimension: C.TextureViewDimension.E2dArray, + dimension: '2d-array', arrayLayerCount: 1, _success: true }, // it is OK to create a 1-layer 2D array texture view on a 2D texture @@ -141,7 +140,7 @@ g.test('creating_texture_view_on_a_2D_array_texture').params([{ _success: true }, // default view works { - dimension: C.TextureViewDimension.E2d, + dimension: '2d', arrayLayerCount: 1, _success: true }, // it is OK to create a 2D texture view on a 2D array texture @@ -205,16 +204,16 @@ g.test('creating_texture_view_on_a_2D_array_texture').params([{ g.test('Using_defaults_validates_the_same_as_setting_values_for_more_than_1_array_layer').params([{ _success: true }, { - format: C.TextureFormat.RGBA8Unorm, + format: 'rgba8unorm', _success: true }, { - format: C.TextureFormat.R8Unorm, + format: 'r8unorm', _success: false }, { - dimension: C.TextureViewDimension.E2dArray, + dimension: '2d-array', _success: true }, { - dimension: C.TextureViewDimension.E2d, + dimension: '2d', _success: false }, { arrayLayerCount: ARRAY_LAYER_COUNT_2D, @@ -222,11 +221,11 @@ g.test('Using_defaults_validates_the_same_as_setting_values_for_more_than_1_arra }, // setting array layers to non-0 means the dimensionality will default to 2D so by itself it causes an error. { arrayLayerCount: ARRAY_LAYER_COUNT_2D, - dimension: C.TextureViewDimension.E2dArray, + dimension: '2d-array', _success: true }, { arrayLayerCount: ARRAY_LAYER_COUNT_2D, - dimension: C.TextureViewDimension.E2dArray, + dimension: '2d-array', mipLevelCount: MIP_LEVEL_COUNT, _success: true }]).fn(async t => { @@ -253,16 +252,16 @@ g.test('Using_defaults_validates_the_same_as_setting_values_for_more_than_1_arra g.test('Using_defaults_validates_the_same_as_setting_values_for_only_1_array_layer').params([{ _success: true }, { - format: C.TextureFormat.RGBA8Unorm, + format: 'rgba8unorm', _success: true }, { - format: C.TextureFormat.R8Unorm, + format: 'r8unorm', _success: false }, { - dimension: C.TextureViewDimension.E2dArray, + dimension: '2d-array', _success: true }, { - dimension: C.TextureViewDimension.E2d, + dimension: '2d', _success: true }, { arrayLayerCount: 0, @@ -301,38 +300,38 @@ g.test('Using_defaults_validates_the_same_as_setting_values_for_only_1_array_lay }, !_success); }); g.test('creating_cube_map_texture_view').params([{ - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', arrayLayerCount: 6, _success: true }, // it is OK to create a cube map texture view with arrayLayerCount == 6 // it is an error to create a cube map texture view with arrayLayerCount != 6 { - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', arrayLayerCount: 3, _success: false }, { - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', arrayLayerCount: 7, _success: false }, { - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', arrayLayerCount: 12, _success: false }, { - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', _success: false }, { - dimension: C.TextureViewDimension.CubeArray, + dimension: 'cube-array', arrayLayerCount: 12, _success: true }, // it is OK to create a cube map array texture view with arrayLayerCount % 6 == 0 // it is an error to create a cube map array texture view with arrayLayerCount % 6 != 0 { - dimension: C.TextureViewDimension.CubeArray, + dimension: 'cube-array', arrayLayerCount: 11, _success: false }, { - dimension: C.TextureViewDimension.CubeArray, + dimension: 'cube-array', arrayLayerCount: 13, _success: false }]).fn(async t => { @@ -353,11 +352,11 @@ g.test('creating_cube_map_texture_view').params([{ }, !_success); }); g.test('creating_cube_map_texture_view_with_a_non_square_texture').params([{ - dimension: C.TextureViewDimension.Cube, + dimension: 'cube', arrayLayerCount: 6 }, // it is an error to create a cube map texture view with width != height. { - dimension: C.TextureViewDimension.CubeArray, + dimension: 'cube-array', arrayLayerCount: 12 } // it is an error to create a cube map array texture view with width != height. ]).fn(async t => { diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/capability_info.js b/tests/wpt/web-platform-tests/webgpu/webgpu/capability_info.js index b2d9353b04d..47d508ac3e3 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/capability_info.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/capability_info.js @@ -2,8 +2,6 @@ * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts **/ -import * as C from '../common/constants.js'; - function keysOf(obj) { return Object.keys(obj); } @@ -456,11 +454,11 @@ export const kTextureAspectInfo = }; export const kTextureAspects = keysOf(kTextureAspectInfo); export const kTextureUsageInfo = { - [C.TextureUsage.CopySrc]: {}, - [C.TextureUsage.CopyDst]: {}, - [C.TextureUsage.Sampled]: {}, - [C.TextureUsage.Storage]: {}, - [C.TextureUsage.OutputAttachment]: {} + [GPUTextureUsage.COPY_SRC]: {}, + [GPUTextureUsage.COPY_DST]: {}, + [GPUTextureUsage.SAMPLED]: {}, + [GPUTextureUsage.STORAGE]: {}, + [GPUTextureUsage.OUTPUT_ATTACHMENT]: {} }; export const kTextureUsages = numericKeysOf(kTextureUsageInfo); // Typedefs for bindings @@ -564,26 +562,26 @@ const kBindingKind = }; // Binding type info const kValidStagesAll = { - validStages: C.ShaderStage.Vertex | C.ShaderStage.Fragment | C.ShaderStage.Compute + validStages: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE }; const kValidStagesStorageWrite = { - validStages: C.ShaderStage.Fragment | C.ShaderStage.Compute + validStages: GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE }; export const kBufferBindingTypeInfo = /* prettier-ignore */ { 'uniform-buffer': { - usage: C.BufferUsage.Uniform, + usage: GPUBufferUsage.UNIFORM, ...kBindingKind.uniformBuf, ...kValidStagesAll }, 'storage-buffer': { - usage: C.BufferUsage.Storage, + usage: GPUBufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesStorageWrite }, 'readonly-storage-buffer': { - usage: C.BufferUsage.Storage, + usage: GPUBufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesAll } @@ -604,17 +602,17 @@ export const kTextureBindingTypeInfo = /* prettier-ignore */ { 'sampled-texture': { - usage: C.TextureUsage.Sampled, + usage: GPUTextureUsage.SAMPLED, ...kBindingKind.sampledTex, ...kValidStagesAll }, 'writeonly-storage-texture': { - usage: C.TextureUsage.Storage, + usage: GPUTextureUsage.STORAGE, ...kBindingKind.storageTex, ...kValidStagesStorageWrite }, 'readonly-storage-texture': { - usage: C.TextureUsage.Storage, + usage: GPUTextureUsage.STORAGE, ...kBindingKind.storageTex, ...kValidStagesAll } @@ -626,6 +624,6 @@ export const kBindingTypeInfo = { ...kBufferBindingTypeInfo, ...kTextureBindingTypeInfo }; export const kBindingTypes = keysOf(kBindingTypeInfo); -export const kShaderStages = [C.ShaderStage.Vertex, C.ShaderStage.Fragment, C.ShaderStage.Compute]; +export const kShaderStages = [GPUShaderStage.VERTEX, GPUShaderStage.FRAGMENT, GPUShaderStage.COMPUTE]; export const kShaderStageCombinations = [0, 1, 2, 3, 4, 5, 6, 7]; //# sourceMappingURL=capability_info.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/gpu_test.js b/tests/wpt/web-platform-tests/webgpu/webgpu/gpu_test.js index d2528c8d84b..e740af1113b 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/gpu_test.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/gpu_test.js @@ -84,7 +84,7 @@ export class GPUTest extends Fixture { const dst = this.createCopyForMapRead(src, expected.buffer.byteLength); this.eventualAsyncExpectation(async niceStack => { const constructor = expected.constructor; - const actual = new constructor((await dst.mapReadAsync())); + const actual = new constructor(await dst.mapReadAsync()); const check = this.checkBuffer(actual, expected); if (check !== undefined) { @@ -201,5 +201,43 @@ got [${failedByteActualValues.join(', ')}]`; this.expectContents(buffer, new Uint8Array(arrayBuffer)); } + expectGPUError(filter, fn) { + this.device.pushErrorScope(filter); + const returnValue = fn(); + const promise = this.device.popErrorScope(); + this.eventualAsyncExpectation(async niceStack => { + const error = await promise; + let failed = false; + + switch (filter) { + case 'none': + failed = error !== null; + break; + + case 'out-of-memory': + failed = !(error instanceof GPUOutOfMemoryError); + break; + + case 'validation': + failed = !(error instanceof GPUValidationError); + break; + } + + if (failed) { + niceStack.message = `Expected ${filter} error`; + this.rec.expectationFailed(niceStack); + } else { + niceStack.message = `Captured ${filter} error`; + + if (error instanceof GPUValidationError) { + niceStack.message += ` - ${error.message}`; + } + + this.rec.debug(niceStack); + } + }); + return returnValue; + } + } //# sourceMappingURL=gpu_test.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/idl/constants/flags.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/idl/constants/flags.spec.js new file mode 100644 index 00000000000..5a6d7868aa5 --- /dev/null +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/idl/constants/flags.spec.js @@ -0,0 +1,53 @@ +/** +* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts +**/ + +export const description = ` +Test the values of flags interfaces (e.g. GPUTextureUsage). +`; +import { makeTestGroup } from '../../../common/framework/test_group.js'; +import { IDLTest } from '../idl_test.js'; +export const g = makeTestGroup(IDLTest); +g.test('BufferUsage').fn(t => { + const expected = { + MAP_READ: 0x0001, + MAP_WRITE: 0x0002, + COPY_SRC: 0x0004, + COPY_DST: 0x0008, + INDEX: 0x0010, + VERTEX: 0x0020, + UNIFORM: 0x0040, + STORAGE: 0x0080, + INDIRECT: 0x0100 + }; + t.assertMembers(GPUBufferUsage, expected); +}); +g.test('TextureUsage').fn(t => { + const expected = { + COPY_SRC: 0x01, + COPY_DST: 0x02, + SAMPLED: 0x04, + STORAGE: 0x08, + OUTPUT_ATTACHMENT: 0x10 + }; + t.assertMembers(GPUTextureUsage, expected); +}); +g.test('ColorWrite').fn(t => { + const expected = { + RED: 0x1, + GREEN: 0x2, + BLUE: 0x4, + ALPHA: 0x8, + ALL: 0xf + }; + t.assertMembers(GPUColorWrite, expected); +}); +g.test('ShaderStage').fn(t => { + const expected = { + VERTEX: 0x1, + FRAGMENT: 0x2, + COMPUTE: 0x4 + }; + t.assertMembers(GPUShaderStage, expected); +}); +//# sourceMappingURL=flags.spec.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/idl/idl_test.js b/tests/wpt/web-platform-tests/webgpu/webgpu/idl/idl_test.js new file mode 100644 index 00000000000..0665ad208cd --- /dev/null +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/idl/idl_test.js @@ -0,0 +1,27 @@ +/** +* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts +**/ + +import { Fixture } from '../../common/framework/fixture.js'; +import { assert } from '../../common/framework/util/util.js'; +export class IDLTest extends Fixture { + /** + * Asserts that an IDL interface has the expected members. + */ + // TODO: exp should allow sentinel markers for unnameable values, such as methods and attributes + // TODO: handle extensions + // TODO: check prototype chains (maybe as separate method) + assertMembers(act, exp) { + const expKeys = Object.keys(exp); + + for (const k of expKeys) { + assert(k in act, () => `Expected key ${k} missing`); + assert(act[k] === exp[k], () => `Value of [${k}] was ${act[k]}, expected ${exp[k]}`); + } + + const actKeys = Object.keys(act); + assert(actKeys.length === expKeys.length, () => `Had ${actKeys.length} keys, expected ${expKeys.length}`); + } + +} +//# sourceMappingURL=idl_test.js.map \ No newline at end of file diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/listing.js b/tests/wpt/web-platform-tests/webgpu/webgpu/listing.js index ea23ab28328..a8b67e72547 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/listing.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/listing.js @@ -245,6 +245,14 @@ export const listing = [ ], "readme": "Tests to check that the WebGPU IDL is correctly implemented, for examples that objects exposed\nexactly the correct members, and that methods throw when passed incomplete dictionaries." }, + { + "file": [ + "idl", + "constants", + "flags" + ], + "description": "Test the values of flags interfaces (e.g. GPUTextureUsage)." + }, { "file": [ "shader" diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/util/texture/layout.js b/tests/wpt/web-platform-tests/webgpu/webgpu/util/texture/layout.js index db9d5dbb435..425aa2020d7 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/util/texture/layout.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/util/texture/layout.js @@ -2,7 +2,6 @@ * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts **/ -import * as C from '../../../common/constants.js'; import { assert, unreachable } from '../../../common/framework/util/util.js'; import { kTextureFormatInfo } from '../../capability_info.js'; import { align, isAligned } from '../math.js'; @@ -112,7 +111,7 @@ export function createTextureUploadBuffer(texelValue, device, format, dimension, } = getTextureCopyLayout(format, dimension, size, options); const [buffer, mapping] = device.createBufferMapped({ size: byteLength, - usage: C.BufferUsage.CopySrc + usage: GPUBufferUsage.COPY_SRC }); assert(texelValue.byteLength === bytesPerBlock); fillTextureDataWithTexelValue(texelValue, format, dimension, mapping, size, options); diff --git a/tests/wpt/web-platform-tests/webgpu/webgpu/web-platform/copyImageBitmapToTexture.spec.js b/tests/wpt/web-platform-tests/webgpu/webgpu/web-platform/copyImageBitmapToTexture.spec.js index de978550acc..efdc21ded93 100644 --- a/tests/wpt/web-platform-tests/webgpu/webgpu/web-platform/copyImageBitmapToTexture.spec.js +++ b/tests/wpt/web-platform-tests/webgpu/webgpu/web-platform/copyImageBitmapToTexture.spec.js @@ -21,7 +21,7 @@ class F extends GPUTest { const rowPitch = calculateRowPitch(width, bytesPerPixel); const dst = this.createCopyForMapRead(src, rowPitch * height); this.eventualAsyncExpectation(async niceStack => { - const actual = new Uint8Array((await dst.mapReadAsync())); + const actual = new Uint8Array(await dst.mapReadAsync()); const check = this.checkBufferWithRowPitch(actual, exp, width, height, rowPitch, bytesPerPixel); if (check !== undefined) { diff --git a/tests/wpt/web-platform-tests/webrtc/RTCStats-helper.js b/tests/wpt/web-platform-tests/webrtc/RTCStats-helper.js index 7bebc2e7b19..6fa6f8e768f 100644 --- a/tests/wpt/web-platform-tests/webrtc/RTCStats-helper.js +++ b/tests/wpt/web-platform-tests/webrtc/RTCStats-helper.js @@ -1,4 +1,4 @@ -R'use strict'; +'use strict'; // Test is based on the following editor draft: // webrtc-pc 20171130